前言1d404fd544258876acda39da99c5bdbf
在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来详细看一下AspectCore中的拦截器使用。
两种配置方式
在AspectCore中,提供拦截器的特性配置和全局配置两种使用方式,并且分别提供AbstractInterceptor
(可用于全局拦截器配置)和AbstractInterceptorAttribute
(可同时用于全局配置和特性配置)两个拦截器基类。下面来分别演示两个拦截器配置方式的使用:
public class CustomInterceptorAttribute : AbstractInterceptorAttribute
{
public override Task Invoke(AspectContext context, AspectDelegate next)
{
return context.Invoke(next);
}
}
那么此时CustomInterceptorAttribute
可以标记在需要拦截的接口,类或者方法上来开启拦截。
Attribute
标记在口,类或者方法上之外,AbstractInterceptor和AbstractInterceptorAttribute并无任何区别) public class CustomInterceptor : AbstractInterceptor
{
public override Task Invoke(AspectContext context, AspectDelegate next)
{
return context.Invoke(next);
}
}
现在我们已经定义了我们自己的拦截器,我使用Microsoft.Extensions.DependencyInjection的集成方式来演示全局拦截器的配置(需安装AspectCore.Extensions.DependencyInjection
包):
IServiceCollection services = new ServiceCollection();
services.AddDynamicProxy(config =>
{
config.Interceptors.AddTyped<CustomInterceptor>();
});
IServiceProvider serviceProvider = services.BuildAspectCoreServiceProvider();
CustomInterceptor便可以拦截由serviceProvider创建的任何服务的方法。
三种拦截器类型
在AspectCore中,提供了TypedInterceptor
,ServiceInterceptor
,DelegateInterceptor
三种拦截器的激活类型。
config.Interceptors.AddTyped<CustomInterceptor>();
配置的全局拦截器,这类拦截器对于每个方法具有唯一的实例。IServiceCollection services = new ServiceCollection();
services.AddTransient<CustomInterceptor>();
我们可以使用ServiceInterceptor
特性激活注册到DI中的拦截器:
[ServiceInterceptor(typeof(CustomInterceptor))]
public interface IService
{
void Foo();
}
或者使用全局配置:
IServiceCollection services = new ServiceCollection();
services.AddTransient<CustomInterceptor>();
services.AddDynamicProxy(config =>
{
config.Interceptors.AddServiced<CustomInterceptor>();
});
IServiceProvider serviceProvider = services.BuildAspectCoreServiceProvider();
Func<AspectDelegate, AspectDelegate>
或Func<AspectContext, AspectDelegate, Task>
的委托来执行拦截,如下面:IServiceCollection services = new ServiceCollection();
services.AddTransient<CustomInterceptor>();
services.AddDynamicProxy(config =>
{
config.Interceptors.AddDelegate( async (content, next) =>
{
Console.WriteLine("delegate interceptor");
await content.Invoke(next);
});
});
IServiceProvider serviceProvider = services.BuildAspectCoreServiceProvider();
使用通配符或者委托配置拦截器
在AspectCore中配置全局拦截器时,可以使用通配符或者委托来限定拦截器的作用范围。
内置提供了Predicates.ForMethod
,Predicates.ForService
,Predicates.ForNameSpace
三个通配符函数:
services.AddDynamicProxy(config =>
{
config.Interceptors.AddTyped<CustomInterceptor>(Predicates.ForMethod("*Query")); //拦截所有Query后缀的方法
config.Interceptors.AddTyped<CustomInterceptor>(Predicates.ForService("*Repository")); //拦截所有Repository后缀的类或接口
config.Interceptors.AddTyped<CustomInterceptor>(Predicates.ForMethod("AspectCoreDemo.*")); //拦截所有AspectCoreDemo及其子命名空间下面的接口或类
});