Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成

Posted 大内老A

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成相关的知识,希望对你有一定的参考价值。


对于.NET Core程序开发来说,依赖注入已经成为无处不在并且“深入骨髓”的东西,不论是在进行业务应用的开发,还是进行基础组件的开发,依赖注入是实现“松耦合”最为理想的方式(没有之一),所以Dora.Interception必须将两者无缝地集成在一起。


01

IInterceptable<T>

由于.NET Core总是采用IServiceProvider接口表示的DI容器来提供注入的依赖服务对象,现在我们得将原始的目标对象转换成能够被拦截代理对象,为此我们提供了一个泛型的服务接口IInterceptable<T>,它的Proxy属性返回的就是这么一个代理对象。

public interface IInterceptable<Twhere Tclass
{
    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());
    }
}

02

InterceptableServiceProvider 

在被依赖类型的构造函数中注入IInterceptable<T>服务的编程方式总显得有点别扭,这要求所有具有AOP需求的组件都需要依赖Dora.Interception,这无疑是不现实的。我们最终需要解决的还是如何让IServiceProvider直接提供可被拦截的代理对象,为此我对.NET Core依赖注入框架的源代码作了一点很小的改动。

这个经过简单修改的IServiceProvider实现类型就是如下这个InterceptableServiceProvider 类型。至于具体修改了什么,并不是一两句话就能说清楚的,这涉及到整个依赖注入框架的设计,有兴趣有查看源代码。

internal sealed class InterceptableServiceProvider : IServiceProviderIDisposableIServiceProviderEngineCallback
{
    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();
    }
    ...
}

03

服务注册

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; }
}

前情回顾



Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成

长按二维码识别关注


以上是关于Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成的主要内容,如果未能解决你的问题,请参考以下文章

Dora.Interception, 为.NET Core度身打造的AOP框架[4]:演示几个典型应用

Dora.Interception,为.NET Core度身打造的AOP框架 [3]:多样化拦截器应用方式

Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成

Dora.Interception,为.NET Core度身打造的AOP框架 [5]:轻松地实现与其他AOP框架的整合

AOP框架Dora.Interception 3.0 [1]: 编程体验

全新升级的AOP框架Dora.Interception[2]: 基于约定的拦截器定义方式