这里所谓的与第三方AOP框架的整合不是说改变Dora.Interception现有的编程,而是恰好相反,即在不改变现有编程模式下采用第三方AOP框架或者自行实现的拦截机制。虽然我们默认提供基于IL Emit实现方式,并且对IL指令进行了深度的优化,但是如果我们真的具有更好的选择,我们可以通过简单的扩展完成对底层拦截机制改变。
一、IInterceptingProxyFactory
对于Dora.Interception来说,方法调用之所有能够被拦截的根源在于我们改变了服务实例的提供方式,原来的对象被替换成了可被拦截的代理对象。针对代理对象的提供体现在如下这个IInterceptingProxyFactory接口上。如果提供类型体现为一个接口,Wrap方法会被调用来创建一个封装目标对象的代理(如果不需要被拦截,则直接返回目标对象);如果提供类型体现为一个类型,Create方法则被用来实现对代理对象的创建,如果不需要被拦截,方法提供的后面两个参数会被用来提供目标对象。
public interface IInterceptingProxyFactory { IServiceProvider ServiceProvider { get; } object Wrap(Type typeToIntercept, object target); object Create(Type typeToIntercept, IServiceProvider serviceProvider, Func<object> targetAccessor = null); }
二、InterceptingProxyFactoryBase
Dora.Interception提供了如下一个实现了IInterceptingProxyFactory接口的基类InterceptingProxyFactoryBase。后者帮助我们实现针对拦截器的解析,解析后的拦截器体现为一个InterceptorDecoration对象。作为它的派生类型只需要实现两个受保护的虚方法Wrap和Create根据解析出来的拦截器实现可被拦截的代理对象的创建。
public abstract class InterceptingProxyFactoryBase : IInterceptingProxyFactory { public IInterceptorResolver InterceptorResolver { get; } public IServiceProvider ServiceProvider { get; } public InterceptingProxyFactoryBase(IInterceptorResolver interceptorResolver, IServiceProvider serviceProvider); public object Create(Type typeToIntercept, IServiceProvider serviceProvider, Func<object> targetAccessor = null); public object Wrap(Type typeToIntercept, object target); protected virtual bool CanIntercept(Type typeToIntercept); protected abstract object Wrap(Type typeToIntercept, object target, InterceptorDecoration interceptors); protected abstract object Create(Type typeToIntercept, IServiceProvider serviceProvider, InterceptorDecoration interceptors); }
如果所示的是InterceptorDecoration, 我们可以得到应用到目标类型中所有方法(包括属性的Get和Set方法)上的拦截器(实际上所有拦截器按照指定顺序构建而成的拦截器管道,最终体现为一个类型为InterceptorDelegate 的委托对象)。
public sealed class InterceptorDecoration { public InterceptorDelegate GetInterceptor(MethodInfo methodInfo); public MethodInfo GetTargetMethod(MethodInfo methodInfo); public bool
