Dora.Interception[3]如何通过特性标注实现拦截器注册?

摘要:在Dora.Interception(github地址,觉得不错不妨给一颗星)中按照约定方式定义的拦截器可以采用多种方式注册到目标方法上。本篇文章介绍最常用的基于“特性标注”的拦截器注册方式,下一篇会介绍另一种基于(Lambda)表达式的注
在Dora.Interception(github地址,觉得不错不妨给一颗星)中按照约定方式定义的拦截器可以采用多种方式注册到目标方法上。本篇文章介绍最常用的基于“特性标注”的拦截器注册方式,下一篇会介绍另一种基于(Lambda)表达式的注册方式。如果原生定义的这两种注册方式不能满足要求,利用框架提供的扩展,我们可以完成任何你想要的拦截器注册手段。(拙著《ASP.NET Core 6框架揭秘》6折优惠,首印送签名专属书签) 目录 一、InterceptorAttribute 特性 二、指定构造拦截器的参数列表 三、将拦截器类型定义成特性 四、合法性检验 五、针对类型、属性的标注 六、拦截的屏蔽 一、InterceptorAttribute 特性拦截器类型可以利用如下这个InterceptorAttribute特性应用到标注的类型、属性和方法上。除了通过Interceptor属性指定拦截器类型之外,我们还可以利用Order属性控制拦截器的执行顺序,该属性默认值为0。该特性的Arguments用来提供构造拦截器对象的参数。 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] public class InterceptorAttribute : Attribute { public Type Interceptor { get; } public object[] Arguments { get; } public int Order { get; set; } public InterceptorAttribute(params object[] arguments) : public InterceptorAttribute(Type? interceptor, params object[] arguments); }二、指定构造拦截器的参数列表拦截器对象是通过依赖注入容器提供的,容器能够自动提供注入到构造函数中对象。如果构造函数包含额外的参数,对应的参数值就需要利用InterceptorAttribute 特性的Arguments属性来提供,此属性由构造函数的arguments参数提供。 public class FoobarInterceptor { public string Name { get; } public FoobarInterceptor(string name, IFoobar foobar) { Name = name; Debug.Assert(foobar is not null); } public ValueTask InvokeAsync(InvocationContext invocationContext) { Console.WriteLine($"FoobarInterceptor '{Name}' is invoked."); return invocationContext.ProceedAsync(); } } public interface IFoobar { } public class Foobar : IFoobar { }对于如上这个拦截器类型FoobarInterceptor,其构造函数定义了一个字符串的参数name用来指定拦截器的名称,当我利用InterceptorAttribute 特性将此拦截器应用到Invoker类型的Invoke1和Invoke2方法上是,就需要按照如下的方式指定具体的名称(Interceptor1和Interceptor2)。 public class Invoker { [FoobarInterceptor("Interceptor1")] public virtual void Invoke1() => Console.WriteLine("Invoker.Invoke1()"); [FoobarInterceptor("Interceptor2")] public virtual void Invoke2() => Console.WriteLine("Invoker.Invoke2()"); }我们按照如下的方式调用Invoker对象的Invoke1和Invoke2方法。
阅读全文