C#声明方法,不参数数目时
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
{
Check.NotNull(services, nameof(services));
var serviceProviderFactory = services.GetSingletonInstanceOrNull
if (serviceProviderFactory == null)
{
throw new AbpException($"Could not find {typeof(IServiceProviderFactory
}
var builder = serviceProviderFactory.CreateBuilder(services);
builderAction?.Invoke(builder);
return serviceProviderFactory.CreateServiceProvider(builder);
}
CreateBuilder函数源码:
///
/// Creates a container builder from an
///
/// The collection of services
///
public ContainerBuilder CreateBuilder(IServiceCollection services)
{
_services = services;
_builder.Populate(services);
return _builder;
}
Populate函数源码:
public static void Populate(
this ContainerBuilder builder,
IServiceCollection services)
{
builder.RegisterType
builder.RegisterType
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
this IRegistrationBuilder
IModuleContainer moduleContainer,
ServiceRegistrationActionList registrationActionList)
where TActivatorData : ReflectionActivatorData
{
// 其余实现
.....
// 这里就是调用OnRegistred函数里面的Action委托
registrationBuilder = registrationBuilder.InvokeRegistrationActions(registrationActionList, serviceType, implementationType);
return registrationBuilder;
}
InvokeRegistrationActions函数源码:
private static IRegistrationBuilder
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
this IRegistrationBuilder
Type serviceType,
IEnumerable
where TActivatorData : ReflectionActivatorData
{
// 启用拦截器
// 如果是接口类型,那么动态创建一个接口代理
// 否则 创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法
if (serviceType.IsInterface)
{
registrationBuilder = registrationBuilder.EnableInterfaceInterceptors();
}
else
{
(registrationBuilder as IRegistrationBuilder
}
foreach (var interceptor in interceptors)
{
// 动态注入拦截器,指定拦截器类型为传入的拦截器
registrationBuilder.InterceptedBy(
typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptor)
);
}
return registrationBuilder;
}
CastleAbpInterceptorAdapter是Castle.Core库通过适配器来定义了一个标准、针对IAbpInterceptor的实现。源码:
// 泛型拦截器为 基于AbpIterceptor的拦截器类型
public class CastleAbpInterceptorAdapter
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
private readonly Lazy
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
}
// 内部调用 Castle.DynamicProxy
public void Proceed()
{
// 省略实现
}
public Task ProceedAsync()
{
// 省略实现
}
private IReadOnlyDictionary
{
// 省略实现
}
}
CastleAbpMethodInvocationAdapter适配器的调用处在CastleAbpInterceptorAdapter适配器类的Intercept函数:
// 调用自定义、基于AbpInterceptor的拦截器
private void InterceptSyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo)
{
_abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation, proceedInfo));
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~