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方法。
