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 = https://www.cnblogs.com/zhiyong-ITNote/p/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));
}
參考:[Abp vNext 原始碼分析] - 3. 依賴注入與攔截器
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/97993.html
標籤:C#
上一篇:C#面向物件--命名空間
