利用消息机制实现.NET AOP(面向方面编程)--利用RealProxy和消息接收器实现多截获

以下代码实现利用RealProxy调用MessageSink链来实现多截获

//TerminatorSink.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;


namespace DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
public class TerminatorSink:IMessageSink
    
{
        
public delegate IMessage MessageTerminatorDelegate(IMessage msg);

        
private MarshalByRefObject _target;
        
private MessageTerminatorDelegate _delegate;

        
public TerminatorSink(MarshalByRefObject target,MessageTerminatorDelegate d)
        
{
            _target 
= target;
            _delegate 
= d;
        }


        
IMessageSink 成员
    }

}


//ObjectWithAspect.cs
using System;

namespace DotNetAOP.MessageSinkWithRealProxy.Framework
{
    [AOPProxy]
    
public abstract class ObjectWithAspects:ContextBoundObject
    
{
    }

}


//MessageChainProxy.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;

namespace DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
public class MessageChainProxy: RealProxy
    
{
        
private MarshalByRefObject _target;
        
private Type _type;

        
public MessageChainProxy(Type type,MarshalByRefObject target): base(type)
        
{
            _target 
= target;
            _type 
= type;
        }


        
public override IMessage Invoke(IMessage msg)
        
{

            IMessageSink sink 
= new TerminatorSink(_target,new TerminatorSink.MessageTerminatorDelegate(ProcessMessage));
            AspectAttribute[] sinks 
= GetAspectAttributes(_type);
            
forint i = sinks.Length - 1; i >= 0 ; i -- )
            
{
                AspectAttribute aspectAttribute 
= sinks[i];
                sink 
= aspectAttribute.CreateAspectSink(sink);
            }

            
return sink.SyncProcessMessage(msg);
        }


        
private AspectAttribute[] GetAspectAttributes(Type type)
        
{
            
return (AspectAttribute[])_type.GetCustomAttributes(typeof(AspectAttribute), true);
        }


        
private IMessage ProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;

            IMethodReturnMessage back 
= null;
            
if (ctr != null)
            
{
                RealProxy defaultProxy 
= RemotingServices.GetRealProxy(_target);
                defaultProxy.InitializeServerObject(ctr);

                back 
= EnterpriseServicesHelper.CreateConstructionReturnMessage
                    (ctr, (MarshalByRefObject)GetTransparentProxy());
            }

            
else
            
{
                back 
= RemotingServices.ExecuteMessage(_target, call);
            }

            
return back;
        }


    }

}


//AsyncReplyHelperSink.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;


namespace DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
class AsyncReplyHelperSink : IMessageSink
    
{
        
public delegate IMessage AsyncReplyHelperSinkDelegate(IMessage msg);

        IMessageSink _nextSink 
= null;
        AsyncReplyHelperSinkDelegate _delegate 
= null;

        
public AsyncReplyHelperSink(IMessageSink nextSink, AsyncReplyHelperSinkDelegate delegates)
        
{
            _nextSink 
= nextSink;
            _delegate 
= delegates;
        }


        
IMessageSink 成员
    }

}


//AspectAttribute.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;

namespace DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
public abstract class AspectAttribute:Attribute
    
{
        
public abstract IMessageSink CreateAspectSink(IMessageSink nextSink);
    }

}

 

//AopProxyAttribute.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;

namespace DotNetAOP.MessageSinkWithRealProxy.Framework
{
    [AttributeUsage(AttributeTargets.Class)]
    
public class AOPProxyAttribute:ProxyAttribute
    
{


        
public override MarshalByRefObject CreateInstance(Type serverType)
        
{
            MarshalByRefObject rawInstance 
=  base.CreateInstance (serverType);
            RealProxy rp 
= new MessageChainProxy(serverType, rawInstance);
            
return (MarshalByRefObject)rp.GetTransparentProxy();
        }


    }

}

 

//以上为框架代码
//以下为Demo代码

//Calculator.cs
using System;

using DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace DotNetAOP.MessageSinkWithRealProxy.Demo
{
    [LogSink,Log2Sink]
    
public class Calculator:ObjectWithAspects
    
{
        
public Calculator()
        
{
        }

        
public double Add(double a , double b)
        
{
            
return a + b;
        }

        
public double Divide(double a, double b)
        
{
            
return a/b;
        }

    }

}


//Log2Sink.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;

using DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace DotNetAOP.MessageSinkWithRealProxy.Demo
{
    
public class Log2Sink : IMessageSink
    
{
        
readonly IMessageSink _nextSink;
        
public Log2Sink(IMessageSink nextSink)
        
{
            _nextSink 
= nextSink;
        }

        
IMessageSink 成员

        
private IMessage AsyncProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;
            
if (ctr != null)
            
{
                Console.WriteLine(
"构造函数:\t" + ctr.MethodName);
            }

            
else
            
{
                Console.WriteLine(
"普通方法:\t" + call.MethodName);
            }

            
return msg;

        }

    }



    [AttributeUsage(AttributeTargets.Class)]
    
public class Log2SinkAttribute : AspectAttribute
    
{
        
public override IMessageSink CreateAspectSink(IMessageSink nextSink)
        
{
            
return new Log2Sink(nextSink);
        }


    }

}


//LOgSink.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;

using DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace DotNetAOP.MessageSinkWithRealProxy.Demo
{
    
public class Log2Sink : IMessageSink
    
{
        
readonly IMessageSink _nextSink;
        
public Log2Sink(IMessageSink nextSink)
        
{
            _nextSink 
= nextSink;
        }

        
IMessageSink 成员

        
private IMessage AsyncProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;
            
if (ctr != null)
            
{
                Console.WriteLine(
"构造函数:\t" + ctr.MethodName);
            }

            
else
            
{
                Console.WriteLine(
"普通方法:\t" + call.MethodName);
            }

            
return msg;

        }

    }



    [AttributeUsage(AttributeTargets.Class)]
    
public class Log2SinkAttribute : AspectAttribute
    
{
        
public override IMessageSink CreateAspectSink(IMessageSink nextSink)
        
{
            
return new Log2Sink(nextSink);
        }


    }

}


//LogSinkAttribute.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;

using DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace DotNetAOP.MessageSinkWithRealProxy.Demo
{
    [AttributeUsage(AttributeTargets.Class)]
    
public class LogSinkAttribute:AspectAttribute
    
{
        
public override IMessageSink CreateAspectSink(IMessageSink nextSink)
        
{
            
return new LogSink(nextSink);
        }


    }

}


//Program.cs
using System;

using DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace DotNetAOP.MessageSinkWithRealProxy.Demo
{
    
/// <summary>
    
/// Class1 的摘要说明。
    
/// </summary>

    class Program
    
{
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            Calculator calc 
= new Calculator();
            Console.WriteLine(calc.Add(
1,2));
            Console.WriteLine(calc.Divide(
2,0));
//            Test2 t2 = new Test2();
//            t2.Te();
            Console.ReadLine();
        }

    }

}

 

需要上面完整代码请留下Email。
年久,源代码已失,不能提供,请见谅
查看其它框架实现请转到此页

利用消息机制实现.NET AOP(面向方面编程)--通过RealProxy实现
利用消息机制实现.NET AOP(面向方面编程)--利用RealProxy和消息接收器实现多截获
利用消息机制实现.NET AOP(面向方面编程)--利用ServerContextSink实现多截获

posted @ 2006-07-26 19:02  Think  阅读(4872)  评论(31编辑  收藏  举报