6. abp中的拦截器(6.21是什么星座)

网友投稿 271 2022-07-31

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([NotNull] this IServiceCollection services, Action builderAction = null)

{

Check.NotNull(services, nameof(services));

var serviceProviderFactory = services.GetSingletonInstanceOrNull>();

if (serviceProviderFactory == null)

{

throw new AbpException($"Could not find {typeof(IServiceProviderFactory).FullName} in {services}.");

}

var builder = serviceProviderFactory.CreateBuilder(services);

builderAction?.Invoke(builder);

return serviceProviderFactory.CreateServiceProvider(builder);

}

CreateBuilder函数源码:

///

/// Creates a container builder from an .

///

/// The collection of services

/// A container builder that can be used to create an .

public ContainerBuilder CreateBuilder(IServiceCollection services)

{

_services = services;

_builder.Populate(services);

return _builder;

}

Populate函数源码:

public static void Populate(

this ContainerBuilder builder,

IServiceCollection services)

{

builder.RegisterType().As();

builder.RegisterType().As();

Register(builder, services);

}

Register函数:

/// 注册拦截器

private static void Register(

ContainerBuilder builder,

IServiceCollection services)

{

var moduleContainer = services.GetSingletonInstance();

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 ConfigureAbpConventions(

this IRegistrationBuilder registrationBuilder,

IModuleContainer moduleContainer,

ServiceRegistrationActionList registrationActionList)

where TActivatorData : ReflectionActivatorData

{

// 其余实现

.....

// 这里就是调用OnRegistred函数里面的Action委托

registrationBuilder = registrationBuilder.InvokeRegistrationActions(registrationActionList, serviceType, implementationType);

return registrationBuilder;

}

InvokeRegistrationActions函数源码:

private static IRegistrationBuilder InvokeRegistrationActions(this IRegistrationBuilder 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 AddInterceptors(

this IRegistrationBuilder registrationBuilder,

Type serviceType,

IEnumerable interceptors)

where TActivatorData : ReflectionActivatorData

{

// 启用拦截器

// 如果是接口类型,那么动态创建一个接口代理

// 否则 创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法

if (serviceType.IsInterface)

{

registrationBuilder = registrationBuilder.EnableInterfaceInterceptors();

}

else

{

(registrationBuilder as IRegistrationBuilder)?.EnableClassInterceptors();

}

foreach (var interceptor in interceptors)

{

// 动态注入拦截器,指定拦截器类型为传入的拦截器

registrationBuilder.InterceptedBy(

typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptor)

);

}

return registrationBuilder;

}

CastleAbpInterceptorAdapter是Castle.Core库通过适配器来定义了一个标准、针对IAbpInterceptor的实现。源码:

// 泛型拦截器为 基于AbpIterceptor的拦截器类型

public class CastleAbpInterceptorAdapter : IInterceptor

where TInterceptor : IAbpInterceptor

{

private static readonly MethodInfo MethodExecuteWithoutReturnValueAsync =

typeof(CastleAbpInterceptorAdapter)

.GetMethod(

nameof(ExecuteWithoutReturnValueAsync),

BindingFlags.NonPublic | BindingFlags.Instance

);

private static readonly MethodInfo MethodExecuteWithReturnValueAsync =

typeof(CastleAbpInterceptorAdapter)

.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 ArgumentsDictionary => _lazyArgumentsDictionary.Value;

private readonly Lazy> _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>(GetArgumentsDictionary);

}

// 内部调用 Castle.DynamicProxy

public void Proceed()

{

// 省略实现

}

public Task ProceedAsync()

{

// 省略实现

}

private IReadOnlyDictionary GetArgumentsDictionary()

{

// 省略实现

}

}

CastleAbpMethodInvocationAdapter适配器的调用处在CastleAbpInterceptorAdapter适配器类的Intercept函数:

// 调用自定义、基于AbpInterceptor的拦截器

private void InterceptSyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo)

{

_abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation, proceedInfo));

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:C#面向对象--命名空间(乘风破浪的姐姐第三季)
下一篇:Winform中在使用VS+svn进行协同开发时添加引用时的相对路径和绝对路径的问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~