欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

6. abp中的拦截器

程序员文章站 2022-05-31 22:18:46
abp拦截器基本定义 拦截器接口定义: 默认抽象类定义: abp的拦截器实现是基于Autofac.Extras.DynamicProxy,这个包依赖两个组件:Autofac、Castle.Core(实质上是调用内部组件DynamicProxy实现动态代理)。关于此组件的资料参考 ".NET 通过 A ......
abp拦截器基本定义

拦截器接口定义:

public interface iabpinterceptor
{
    void intercept(iabpmethodinvocation invocation);

    task interceptasync(iabpmethodinvocation invocation);
}

默认抽象类定义:

public abstract class abpinterceptor : iabpinterceptor
{
    public abstract void intercept(iabpmethodinvocation invocation);

    public virtual task interceptasync(iabpmethodinvocation invocation)
    {
        intercept(invocation);
        return task.completedtask;
    }
}

abp的拦截器实现是基于autofac.extras.dynamicproxy,这个包依赖两个组件:autofac、castle.core(实质上是调用内部组件dynamicproxy实现动态代理)。关于此组件的资料参考

.net 通过 autofac 和 dynamicproxy 实现aop

type interceptors

abp拦截器的设计轨迹

此类的作用就是将aspnetcore默认的di服务容器(servicecollection)替换为autofac。

public static iserviceprovider buildserviceproviderfromfactory<tcontainerbuilder>([notnull] this iservicecollection services, action<tcontainerbuilder> builderaction = null)
{
    check.notnull(services, nameof(services));

    var serviceproviderfactory = services.getsingletoninstanceornull<iserviceproviderfactory<tcontainerbuilder>>();
    if (serviceproviderfactory == null)
    {
        throw new abpexception($"could not find {typeof(iserviceproviderfactory<tcontainerbuilder>).fullname} in {services}.");
    }

    var builder = serviceproviderfactory.createbuilder(services);
    builderaction?.invoke(builder);
    return serviceproviderfactory.createserviceprovider(builder);
}

createbuilder函数源码:

/// <summary>
/// creates a container builder from an <see cref="t:microsoft.extensions.dependencyinjection.iservicecollection" />.
/// </summary>
/// <param name="services">the collection of services</param>
/// <returns>a container builder that can be used to create an <see cref="t:system.iserviceprovider" />.</returns>
public containerbuilder createbuilder(iservicecollection services)
{
    _services = services;
    
    _builder.populate(services);
    
    return _builder;
}

populate函数源码:

public static void populate(
        this containerbuilder builder,
        iservicecollection services)
{
    builder.registertype<autofacserviceprovider>().as<iserviceprovider>();
    builder.registertype<autofacservicescopefactory>().as<iservicescopefactory>();

    register(builder, services);
}

register函数:

/// 注册拦截器
private static void register(
        containerbuilder builder,
        iservicecollection services)
{
    var modulecontainer = services.getsingletoninstance<imodulecontainer>();
    var registrationactionlist = services.getregistrationactionlist();

    // 遍历di服务容器中的服务
    foreach (var service in services)
    {
        if (service.implementationtype != null)
        {
            // 判断服务是否是泛型
            var servicetypeinfo = service.servicetype.gettypeinfo();
            if (servicetypeinfo.isgenerictypedefinition)
            {
                builder
                    .registergeneric(service.implementationtype)
                    .as(service.servicetype)
                    .configurelifecycle(service.lifetime)
                    .configureabpconventions(modulecontainer, registrationactionlist);
            }
            else
            {
                builder
                    .registertype(service.implementationtype)
                    .as(service.servicetype)
                    .configurelifecycle(service.lifetime)
                    .configureabpconventions(modulecontainer, registrationactionlist);
            }
        }
        // 其余实现
        ......
    }
}

configureabpconventions函数源码:

public static iregistrationbuilder<tlimit, tactivatordata, tregistrationstyle> configureabpconventions<tlimit, tactivatordata, tregistrationstyle>(
    this iregistrationbuilder<tlimit, tactivatordata, tregistrationstyle> registrationbuilder, 
    imodulecontainer modulecontainer, 
    serviceregistrationactionlist registrationactionlist)
where tactivatordata : reflectionactivatordata
{
    // 其余实现
    .....
    
    // 这里就是调用onregistred函数里面的action委托
    registrationbuilder = registrationbuilder.invokeregistrationactions(registrationactionlist, servicetype, implementationtype);

    return registrationbuilder;
}

invokeregistrationactions函数源码:

private static iregistrationbuilder<tlimit, tactivatordata, tregistrationstyle> invokeregistrationactions<tlimit, tactivatordata, tregistrationstyle>(this iregistrationbuilder<tlimit, tactivatordata, tregistrationstyle> registrationbuilder, serviceregistrationactionlist registrationactionlist, type servicetype, type implementationtype) 
    where tactivatordata : reflectionactivatordata
{
    var serviceregistredargs = new onserviceregistredcontext(servicetype, implementationtype);

    foreach (var registrationaction in registrationactionlist)
    {
        // 调用onregistred函数里面的action委托,注入拦截器
        registrationaction.invoke(serviceregistredargs);
    }

    //如果有拦截器
    if (serviceregistredargs.interceptors.any())
    {
        // 在某个服务类型(servicetype)类上注册拦截器
        registrationbuilder = registrationbuilder.addinterceptors(
            servicetype,
            serviceregistredargs.interceptors
        );
    }

    return registrationbuilder;
}

addinterceptors函数源码:

private static iregistrationbuilder<tlimit, tactivatordata, tregistrationstyle> addinterceptors<tlimit, tactivatordata, tregistrationstyle>(
    this iregistrationbuilder<tlimit, tactivatordata, tregistrationstyle> registrationbuilder, 
    type servicetype,
    ienumerable<type> interceptors)
    where tactivatordata : reflectionactivatordata
    {
        // 启用拦截器
        // 如果是接口类型,那么动态创建一个接口代理
        // 否则 创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法
        if (servicetype.isinterface)
        {
            registrationbuilder = registrationbuilder.enableinterfaceinterceptors();
        }
        else
        {
            (registrationbuilder as iregistrationbuilder<tlimit, concretereflectionactivatordata, tregistrationstyle>)?.enableclassinterceptors();
        }
    
        foreach (var interceptor in interceptors)
        {
            // 动态注入拦截器,指定拦截器类型为传入的拦截器
            registrationbuilder.interceptedby(
               typeof(castleabpinterceptoradapter<>).makegenerictype(interceptor)
            );
        }
    
        return registrationbuilder;
    }

castleabpinterceptoradapter是castle.core库通过适配器来定义了一个标准、针对iabpinterceptor的实现。源码:

// 泛型拦截器为 基于abpiterceptor的拦截器类型
public class castleabpinterceptoradapter<tinterceptor> : iinterceptor
    where tinterceptor : iabpinterceptor
{
    private static readonly methodinfo methodexecutewithoutreturnvalueasync =
        typeof(castleabpinterceptoradapter<tinterceptor>)
            .getmethod(
                nameof(executewithoutreturnvalueasync),
                bindingflags.nonpublic | bindingflags.instance
            );

    private static readonly methodinfo methodexecutewithreturnvalueasync =
        typeof(castleabpinterceptoradapter<tinterceptor>)
            .getmethod(
                nameof(executewithreturnvalueasync),
                bindingflags.nonpublic | bindingflags.instance
            );

    // 这里的tinterceptor就是在interceptedby方法那里传入的拦截器类型
    // 也就是我们基于abpinterceptor抽象类创建的拦截器
    private readonly tinterceptor _abpinterceptor;

    public castleabpinterceptoradapter(tinterceptor abpinterceptor)
    {
        _abpinterceptor = abpinterceptor;
    }
    
    // 其余代码
}

iabpmethodinvocation接口封装了被拦截方法调用时的各种参数,例如,被拦截方法在调用时所传递的参数,返回值类型,方法定义等。castle.core库通过适配器来定义了一个标准、针对iabpmethodinvocation的实现。源码:

public class castleabpmethodinvocationadapter : iabpmethodinvocation
{
    public object[] arguments => invocation.arguments;

    public ireadonlydictionary<string, object> argumentsdictionary => _lazyargumentsdictionary.value;
    private readonly lazy<ireadonlydictionary<string, object>> _lazyargumentsdictionary;

    public type[] genericarguments => invocation.genericarguments;

    public object targetobject => invocation.invocationtarget ?? invocation.methodinvocationtarget;

    public methodinfo method => invocation.methodinvocationtarget ?? invocation.method;

    public object returnvalue
    {
        get => _actualreturnvalue ?? invocation.returnvalue;
        set => invocation.returnvalue = value;
    }

    private object _actualreturnvalue;

    protected iinvocation invocation { get; }
    protected iinvocationproceedinfo proceedinfo { get; }

    public castleabpmethodinvocationadapter(iinvocation invocation, iinvocationproceedinfo proceedinfo)
    {
        invocation = invocation;
        proceedinfo = proceedinfo;

        _lazyargumentsdictionary = new lazy<ireadonlydictionary<string, object>>(getargumentsdictionary);
    }

    // 内部调用 castle.dynamicproxy
    public void proceed()
    {
        // 省略实现
    }

    public task proceedasync()
    {
        // 省略实现
    }

    private ireadonlydictionary<string, object> getargumentsdictionary()
    {
        // 省略实现
    }
}

castleabpmethodinvocationadapter适配器的调用处在castleabpinterceptoradapter适配器类的intercept函数:

// 调用自定义、基于abpinterceptor的拦截器
private void interceptsyncmethod(iinvocation invocation, iinvocationproceedinfo proceedinfo)
{
    _abpinterceptor.intercept(new castleabpmethodinvocationadapter(invocation, proceedinfo));
}

参考:[abp vnext 源码分析] - 3. 依赖注入与拦截器