博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dora.Interception,为.NET Core度身打造的AOP框架 [5]:轻松地实现与其他AOP框架的整合...
阅读量:6576 次
发布时间:2019-06-24

本文共 3835 字,大约阅读时间需要 12 分钟。

这里所谓的与第三方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 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 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 IsInterceptable(MethodInfo methodInfo);    public IReadOnlyDictionary
Interceptors { get; } public bool IsEmpty { get; } public IReadOnlyDictionary
MethodBasedInterceptors { get; } public IReadOnlyDictionary
PropertyBasedInterceptors { get; }}public class MethodBasedInterceptorDecoration{ public InterceptorDelegate Interceptor { get; } public MethodInfo Method { get; }}public class PropertyBasedInterceptorDecoration{ public PropertyInfo Property { get; } public MethodBasedInterceptorDecoration GetMethodBasedInterceptor { get; } public MethodBasedInterceptorDecoration SetMethodBasedInterceptor { get; }}

自定义的IInterceptingProxyFactory实现只需要按照普通的服进行注册即可。

三、针对Castle的集成

由于Castle原生的框架并没有提供针对Task的支持,所以我们利用另一个名为将Castle的拦截实现整合到Dora.Interception。具体的实现体现在如下这个DynamicProxyFactory中。该类型对应的NuGet包为“Dora.Interception.Castle”。

public class DynamicProxyFactory : InterceptingProxyFactoryBase{       public DynamicProxyFactory(IInterceptorResolver interceptorResolver, IServiceProvider serviceProvider);    protected override object Create(Type typeToIntercept, IServiceProvider serviceProvider, InterceptorDecoration interceptors);    protected override object Wrap(Type typeToIntercept, object target, InterceptorDecoration interceptors);}

如果需要采用基于Caslte的拦截实现机制,我们只需要做如下的设置即可。

public class Startup{    public void ConfigureServices(IServiceCollection services)    {                services            ...            AddInterception(builder=>builder.SetCastleDynamicProxy());    }    ...}

或者

public class Startup{    public IServiceProvider ConfigureServices(IServiceCollection services)    {                return services            ...            .BuildInterceptableServiceProvider(builder=>builder.SetCastleDynamicProxy());    }    ...}

转载地址:http://lfgjo.baihongyu.com/

你可能感兴趣的文章
Jolt大奖获奖图书
查看>>
drools 将添加switch支持
查看>>
android中webview空间通过Img 标签显示sd卡中 的图片
查看>>
android socket编程实例
查看>>
使用SimpleDateFormat出现时差
查看>>
关于linux低端内存
查看>>
url 的正则表达式:path-to-regexp
查看>>
ubuntu 16.04 安装PhpMyAdmin
查看>>
安卓开启多个服务
查看>>
设置分录行按钮监听事件
查看>>
C Primer Plus 第5章 运算符、表达式和语句 5.2基本运算符
查看>>
蓝牙手柄按键码
查看>>
redis启动失败
查看>>
Navicat for PostgreSQL 怎么维护数据库和表
查看>>
java并发库之Executors常用的创建ExecutorService的几个方法说明
查看>>
Spring框架错误之org.springframework.beans.factory.BeanCreationException
查看>>
23种设计模式(1):单例模式
查看>>
socket 编程入门教程(五)UDP原理:4、“有连接”的UDP
查看>>
linux sort 命令详解
查看>>
Jquery获取iframe中的元素
查看>>