当前位置: 移动技术网 > IT编程>开发语言>c# > 6. abp中的拦截器

6. abp中的拦截器

2019年12月01日  | 移动技术网IT编程  | 我要评论
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. 依赖注入与拦截器

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网