zoukankan      html  css  js  c++  java
  • 聊聊AspectCore动态代理中的拦截器

    前言

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

    两种配置方式

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

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

    那么此时CustomInterceptorAttribute可以标记在需要拦截的接口,类或者方法上来开启拦截。

    • 全局拦截器配置。我们继承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包):

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

    CustomInterceptor便可以拦截由serviceProvider创建的任何服务的方法。

    三种拦截器类型

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

    • TypedInterceptor
      标记在接口,类或者方法上的特性拦截器或者使用上面config.Interceptors.AddTyped<CustomInterceptor>();配置的全局拦截器,这类拦截器对于每个方法具有唯一的实例。
    • ServiceInterceptor
      注册到DI并从DI激活使用的拦截器。这类拦截器的生命周期同注册到DI时的生命周期一致。如下面我们注册一个瞬态的ServiceInterceptor:
    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();
    
    
    • 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群: 306531723

    相关文章

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

  • 相关阅读:
    我们是如何实现DevOps的
    cmp命令
    全排列II
    chown命令
    两个数组的交集II
    MVVM模式的理解
    chmod命令
    路径总和
    cat命令
    跳水板
  • 原文地址:https://www.cnblogs.com/liuhaoyang/p/interceptor-in-aspectcore-part-1.html
Copyright © 2011-2022 走看看