一、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 IsInterceptable(MethodInfo methodInfo); ???public IReadOnlyDictionary<int, InterceptorDelegate> Interceptors { get; } ???public bool IsEmpty { get; } ???public IReadOnlyDictionary<MethodInfo, MethodBasedInterceptorDecoration> MethodBasedInterceptors { get; } ???public IReadOnlyDictionary<PropertyInfo, PropertyBasedInterceptorDecoration> 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.Core.AsyncInterceptor将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()); ???} ???...}
[1]:更加简练的编程体验
[2]:基于约定的拦截器定义方式
[3]:多样性的拦截器应用方式
[4]:与依赖注入框架的深度整合
[5]:对拦截机制的灵活定制
Dora.Interception,为.NET Core度身打造的AOP框架 [5]:轻松地实现与其他AOP框架的整合
原文地址:https://www.cnblogs.com/linybo/p/10053040.html
知识推荐
- css - 盒子模型
- webpack打包问题
- Kubernetes里的secret最基本的用法
- 多实例集群部署下的图片上传
- Json返回结果为null属性不显示解决方法
- HTML(5)基础
- CSS 高度(css height)
- web前端学习(五)(6)-- jQuery的扩展与noConflict
- asp.net core 2.0 定时任务
- d3.js入门之DOM操作
- 【vue-cli 3.0】 vue.config.js配置 - 路径别名
- HTML5按键打开摄像头和拍照
- ThinkPHP5 ajax使用
- php实现每日签到功能
- 上传文件Base64格式(React)
- 我是这样发现ISP劫持HTTP请求的
- IUM工程项目js概念模拟
- 【文章学习】监控网页卡顿、崩溃