一、IInterceptable<T>
由于.NET Core总是采用IServiceProvider接口表示的DI容器来提供注入的依赖服务对象,现在我们得将原始的目标对象转换成能够被拦截代理对象,为此我们提供了一个泛型的服务接口IInterceptable<T>,它的Proxy属性返回的就是这么一个代理对象。
public interface IInterceptable<T> where T: class{ ???T Proxy { get; }}
由于着了一个帮助我们提供可拦截代理的IInterceptable<T>服务,我们就可以在需要拦截目标类型的地方按照如下的方式注入该服务,并利用其Proxy属性得到这个可被拦截的代理。
public class HomeController : Controller{ ???private readonly ISystemClock _clock; ???public HomeController(IInterceptable<ISystemClock> clockAccessor) ???{ ???????_clock = clockAccessor.Proxy; ???????Debug.Assert(typeof(SystemClock) != _clock.GetType()); ???}}
二、让IServiceProvider直接代理对象
在被依赖类型的构造函数中注入IInterceptable<T>服务的编程方式总显得有点别扭,这要求所有具有AOP需求的组件都需要依赖Dora.Interception,这无疑是不现实的。我们最终需要解决的还是如何让IServiceProvider直接提供可被拦截的代理对象,为此我对.NET Core依赖注入框架的源代码作了一点很小的改动。这个经过简单修改的IServiceProvider实现类型就是如下这个InterceptableServiceProvider 类型。至于具体修改了什么,并不是一两句话就能说清楚的,这涉及到整个依赖注入框架的设计,有兴趣有查看源代码。
internal sealed class InterceptableServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback{ ???internal InterceptableServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options, IInterceptingProxyFactory interceptingProxyFactory); ???public void Dispose(); ???public object GetService(Type serviceType); ???void IServiceProviderEngineCallback.OnCreate(IServiceCallSite callSite); ???void IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope);}
我们在Startup类型的ConfigureServices方法中,调用IServiceCollection的扩展方法BuildInterceptableServiceProvider创建的就是这么一个InterceptableServiceProvider 对象。
public class Startup{ ???public IServiceProvider ConfigureServices(IServiceCollection services) ???{ ???????return services ???????????... ???????????.BuildInterceptableServiceProvider(); ???} ???...}
三、服务注册
Dora.Interception所需的服务注册都是通过调用IServiceCollection的扩展方法AddInterception来完成的,由于AddInterception会调整现有的服务注册以支持上面介绍的IInterceptable<T>服务,所以AddInterception方法的调用需要放在所有服务注册结束之后。创建InterceptableServiceProvider的BuildInterceptableServiceProvider方法内部会调用AddInterception方法,但是不会对现有的服务注册作任何修改。
public static class ServiceCollectionExtensions{ ???public static IServiceCollection AddInterception(this IServiceCollection services, Action<InterceptionBuilder> configure = null); ???public static IServiceProvider BuildInterceptableServiceProvider(this IServiceCollection services, Action<InterceptionBuilder> configure = null); ???public static IServiceProvider BuildInterceptableServiceProvider(this IServiceCollection services, bool validateScopes, Action<InterceptionBuilder> configure = null);}
AddInterception和BuildInterceptableServiceProvider方法均定义了一个Action<InterceptionBuilder>类型的参数,我们可以利用它对注册的服务做进一步定制。比如如果我们需要实现自定义的拦截器注册方式,只需要将自定义的IInterceptorProviderResolver对象添加到InterceptorProviderResolvers 属性表示的集合中即可。
public class InterceptionBuilder{ ???public InterceptionBuilder(IServiceCollection services); ???public InterceptorProviderResolverCollection InterceptorProviderResolvers { get; } ???public IServiceCollection Services { get; }}
[1]:更加简练的编程体验
[2]:基于约定的拦截器定义方式
[3]:多样性的拦截器应用方式
[4]:与依赖注入框架的深度整合
[5]:对拦截机制的灵活定制
Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成
原文地址:https://www.cnblogs.com/linybo/p/10053032.html
知识推荐
- js对象
- mui使用webpack时svg问题(postcss-svgo)
- webpack插件机制
- django HttpResponse的用法
- 使用jQuery增加或删除元素(内容)
- Apache 配置301跳转
- js事件类型
- js-检测字符串出现次数最多,并返回
- Kubernetes的Rolling Update实战
- HTTP协议详解
- css模型框
- Linux服务器---apache支持cgi
- Http常见的响应头
- ASP.NET CORE依赖注入&AutoFac
- 如何从外网访问内网Elasticsearch WEB
- nonce和timestamp在Http安全协议中的作用
- 学习React前端框架,报错 ???'React' must be in scope when using JSX ?react/react-in-jsx-scope
- webpack基本使用教程