动态织入的AOP实现

转载自:http://www.cnblogs.com/luminji/archive/2012/01/10/2318211.html

动态织入的AOP实现,有两种方法:

第一类,借助于Remoting命名空间下的几个类,通过获取当前上下文及反射的机制来实现,这需要被AOP的类需要继承自arshalByRefObject或者ContextBoundObject;

第二类,原理是基于动态代理的思想,即在运行时动态构造一个原有类的子类,这样就可以在子类的重载方法中插入额外代码。

这两类方法,都有显著的不足,前者直接要求我们继承固定类,后者呢,除非父类方法被定义为virtual,或者方法定义于某个接口,否则就不能被重载,这就是得“拦截”并不是可以对任意的方法进行的。

动态织入局限于CLR的限制,不能实现对任何方法进行AOP,如果要突破这个限制,只能采用静态织入的方法,静态织入采用。静态织入突破OO设计模式,可以拦截所有的方法甚至构造函数或属性访问器,因为它是直接修改IL。还有,因为它在运行前修改原有程序集,也就基本不存在运行时的性能损失问题了。它的不足,一方面是框架较复杂,实现较麻烦,依赖于对底层的IL指令集的操纵;

一:继承自ContextBoundObject的实现

帮助类:


  
  
public class LogHandler : ICallHandler
{
     /// <summary>
     /// 执行顺序
     /// </summary>
     public int Order { get ; set ; }
     public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
     {
         Console.WriteLine( "方法名: {0}" , input.MethodBase.Name);
         Console.WriteLine( "参数:" );
         for (var i = 0; i < input.Arguments.Count; i++)
         {
             Console.WriteLine( "{0}: {1}" , input.Arguments.ParameterName(i), input.Arguments[i]);
         }
         Console.WriteLine( "方法执行前的处理" );
         var retvalue = getNext()(input, getNext);
         Console.WriteLine( "方法执行后的处理" );
         return retvalue;
     }
}
 
public class LogHandlerAttribute : HandlerAttribute
{
     public override ICallHandler CreateHandler(IUnityContainer container)
     {
         return new LogHandler();
     }
}
调用方:

public interface ISample
{
    [LogHandler]
    void DoSomething();
    void DoSomethingNoAop();
}
 
class Sample1 : ISample
{
    public void DoSomething()
    {
        Console.WriteLine("Sample1 do something");
    }
 
    public void DoSomethingNoAop()
    {
        Console.WriteLine("Sample1 do something no aop");
    }
}
 
public class SampleClass
{
 
    [LogHandler]
    public virtual void SampleVirtual()
    {
        Console.WriteLine("Virtual method");
    }
 
    public void Sample()
    {
        Console.WriteLine("Sampe method");
    }
}
 
class Program {
 
    static void Main() {
        //针对接口
        var container1 = new UnityContainer()
            .AddNewExtension<Interception>()
            .RegisterType<ISample, Sample1>();
        container1
            .Configure<Interception>()
            .SetInterceptorFor<ISample>(new InterfaceInterceptor());
        container1
            .Configure<Interception>()
            .SetInterceptorFor<SampleClass>(new VirtualMethodInterceptor());
        var sample1 = container1.Resolve<ISample>();
        sample1.DoSomething();
        sample1.DoSomethingNoAop();
 
        //针对虚拟方法
        var sample2 = container1.Resolve<SampleClass>();
        sample2.SampleVirtual();
        sample2.Sample();
 
        Console.ReadKey();
    }
 
}

可以看到,第二种方法是用Unity实现的,关于Unity,这里多说两句:

Unity的AOP可以从3种标记的情况拦截:
TransparentProxyInterceptor:直接在类的方法上进行标记,但是这个类必须继承MarshalByRefObject;
VirtualMethod:直接在类的虚方法上进行标记,如上文代码;
InterfaceInterceptor:在接口的方法上进行标记,如上文代码;

代码下载:ConsoleApplication1.rarConsoleApplication2.rar





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值