聊聊AspectCore动态代理中的拦截器

前言

在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,因为介绍的比较浅显,也有很多同窗留言询问拦截器的配置,那么在这篇文章中,咱们来详细看一下AspectCore中的拦截器使用。html

两种配置方式

在AspectCore中,提供拦截器的特性配置和全局配置两种使用方式,而且分别提供AbstractInterceptor(可用于全局拦截器配置)和AbstractInterceptorAttribute(可同时用于全局配置和特性配置)两个拦截器基类。下面来分别演示两个拦截器配置方式的使用:git

  • 特性拦截器。咱们继承AbstractInterceptorAttribute来实现一个本身的特性拦截器
public class CustomInterceptorAttribute : AbstractInterceptorAttribute
 {
     public override Task Invoke(AspectContext context, AspectDelegate next)
     {
         return context.Invoke(next);
     }
 }

那么此时CustomInterceptorAttribute能够标记在须要拦截的接口,类或者方法上来开启拦截。github

  • 全局拦截器配置。咱们继承AbstractInterceptor来实现一个本身的特性拦截器(除不能做为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包):async

IServiceCollection services = new ServiceCollection();
services.AddDynamicProxy(config =>
{
    config.Interceptors.AddTyped<CustomInterceptor>();
});
IServiceProvider serviceProvider = services.BuildAspectCoreServiceProvider();

CustomInterceptor即可以拦截由serviceProvider建立的任何服务的方法。ide

三种拦截器类型

在AspectCore中,提供了TypedInterceptor,ServiceInterceptor,DelegateInterceptor三种拦截器的激活类型。函数

  • TypedInterceptor 标记在接口,类或者方法上的特性拦截器或者使用上面config.Interceptors.AddTyped<CustomInterceptor>();配置的全局拦截器,这类拦截器对于每一个方法具备惟一的实例。
  • ServiceInterceptor 注册到DI并从DI激活使用的拦截器。这类拦截器的生命周期同注册到DI时的生命周期一致。以下面咱们注册一个瞬态的ServiceInterceptor:
IServiceCollection services = new ServiceCollection();

services.AddTransient<CustomInterceptor>();

咱们能够使用ServiceInterceptor特性激活注册到DI中的拦截器:ui

[ServiceInterceptor(typeof(CustomInterceptor))]
public interface IService
{
    void Foo();
}

或者使用全局配置:spa

IServiceCollection services = new ServiceCollection();

 services.AddTransient<CustomInterceptor>();

 services.AddDynamicProxy(config =>
 {
     config.Interceptors.AddServiced<CustomInterceptor>();
 });
 IServiceProvider serviceProvider = services.BuildAspectCoreServiceProvider();
  • DelegateInterceptor 在使用全局的拦截器配置时,咱们也能够不定义具体的拦截器类,而直接使用签名为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.ForNamespace("AspectCoreDemo.*")); //拦截全部AspectCoreDemo及其子命名空间下面的接口或类
 });

有问题反馈

若是您有任何问题,请提交 Issue 给咱们。
Github : https://github.com/dotnetcore/AspectCore-Framework
AspectCore QQ群: 306531723code

相关文章

Asp.Net Core轻量级Aop解决方案:AspectCore
AspectCore.Extension.Reflection : .NET Core反射扩展库
AspectCore中的IoC容器和依赖注入
使用AspectCore动态代理

相关文章
相关标签/搜索