[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);
}二、指定构造拦截器的参数列表
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 { }
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方法。
var invoker = new ServiceCollection()
.AddSingleton<Invoker>()
.AddSingleton<IFoobar, Foobar>()
.BuildInterceptableServiceProvider()
.GetRequiredService<Invoker>();
invoker.Invoke1();
invoker.Invoke2();
public class FoobarInterceptorAttribute: InterceptorAttribute
{
public string Name { get; }
public FoobarInterceptorAttribute(string name) => Name = name;
public ValueTask InvokeAsync(InvocationContext invocationContext)
{
Console.WriteLine($"FoobarInterceptor '{Name}' is invoked.");
return invocationContext.ProceedAsync();
}
}
那么它就可以按照如下的方式标注到Invoker类型的两个方法上(源代码)。
public class Invoker
{
[FoobarInterceptor("Interceptor1")]
public virtual void Invoke1() => Console.WriteLine("Invoker.Invoke1()");
[FoobarInterceptor("Interceptor2")]
public virtual void Invoke2() => Console.WriteLine("Invoker.Invoke2()");
}四、合法性检验
public class Foo
{
[FoobarInterceptor]
public void M() { }
}
public class Bar
{
[FoobarInterceptor]
public object? P { get; set; }
}
[FoobarInterceptor]
public class Baz
{
public void M() { }
}
public class FoobarInterceptorAttribute : InterceptorAttribute
{
public ValueTask InvokeAsync(InvocationContext invocationContext)
{
var method = invocationContext.MethodInfo;
Console.WriteLine($"{method.DeclaringType!.Name}.{method.Name} is intercepted.");
return invocationContext.ProceedAsync();
}
}
[FoobarInterceptor]
public class Foo
{
public virtual void M1() { }
public void M2() { }
public virtual object? P1 { get; set; }
public object? P2 { get; set; }
}
public class Bar
{
[FoobarInterceptor]
public virtual object? P1 { get; set; }
public virtual object? P2 { get; [FoobarInterceptor] set; }
}
我们利用如下的程序来检验针对Foo和Bar对象所有方法和属性的调用,那么被拦截器拦截下来。
var provider = new ServiceCollection()
.AddSingleton<Foo>()
.AddSingleton<Bar>()
.BuildInterceptableServiceProvider();
var foo = provider.GetRequiredService<Foo>();
var bar = provider.GetRequiredService<Bar>();
foo.M1();
foo.M2();
foo.P1 = null;
_ = foo.P1;
foo.P2 = null;
_ = foo.P2;
Console.WriteLine();
bar.P1 = null;
_ = bar.P1;
bar.P2 = null;
_ = bar.P2;
[FoobarInterceptor]
public class Foo
{
[NonInterceptable]
public virtual void M() { }
[NonInterceptable]
public virtual object? P1 { get; set; }
public virtual object? P2 { [NonInterceptable] get; set; }
}
[NonInterceptable]
public class Bar
{
[FoobarInterceptor]
public virtual void M() { }
[FoobarInterceptor]
public virtual object? P { get; set; }
}
[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);
}二、指定构造拦截器的参数列表
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 { }
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方法。
var invoker = new ServiceCollection()
.AddSingleton<Invoker>()
.AddSingleton<IFoobar, Foobar>()
.BuildInterceptableServiceProvider()
.GetRequiredService<Invoker>();
invoker.Invoke1();
invoker.Invoke2();
public class FoobarInterceptorAttribute: InterceptorAttribute
{
public string Name { get; }
public FoobarInterceptorAttribute(string name) => Name = name;
public ValueTask InvokeAsync(InvocationContext invocationContext)
{
Console.WriteLine($"FoobarInterceptor '{Name}' is invoked.");
return invocationContext.ProceedAsync();
}
}
那么它就可以按照如下的方式标注到Invoker类型的两个方法上(源代码)。
public class Invoker
{
[FoobarInterceptor("Interceptor1")]
public virtual void Invoke1() => Console.WriteLine("Invoker.Invoke1()");
[FoobarInterceptor("Interceptor2")]
public virtual void Invoke2() => Console.WriteLine("Invoker.Invoke2()");
}四、合法性检验
public class Foo
{
[FoobarInterceptor]
public void M() { }
}
public class Bar
{
[FoobarInterceptor]
public object? P { get; set; }
}
[FoobarInterceptor]
public class Baz
{
public void M() { }
}
public class FoobarInterceptorAttribute : InterceptorAttribute
{
public ValueTask InvokeAsync(InvocationContext invocationContext)
{
var method = invocationContext.MethodInfo;
Console.WriteLine($"{method.DeclaringType!.Name}.{method.Name} is intercepted.");
return invocationContext.ProceedAsync();
}
}
[FoobarInterceptor]
public class Foo
{
public virtual void M1() { }
public void M2() { }
public virtual object? P1 { get; set; }
public object? P2 { get; set; }
}
public class Bar
{
[FoobarInterceptor]
public virtual object? P1 { get; set; }
public virtual object? P2 { get; [FoobarInterceptor] set; }
}
我们利用如下的程序来检验针对Foo和Bar对象所有方法和属性的调用,那么被拦截器拦截下来。
var provider = new ServiceCollection()
.AddSingleton<Foo>()
.AddSingleton<Bar>()
.BuildInterceptableServiceProvider();
var foo = provider.GetRequiredService<Foo>();
var bar = provider.GetRequiredService<Bar>();
foo.M1();
foo.M2();
foo.P1 = null;
_ = foo.P1;
foo.P2 = null;
_ = foo.P2;
Console.WriteLine();
bar.P1 = null;
_ = bar.P1;
bar.P2 = null;
_ = bar.P2;
[FoobarInterceptor]
public class Foo
{
[NonInterceptable]
public virtual void M() { }
[NonInterceptable]
public virtual object? P1 { get; set; }
public virtual object? P2 { [NonInterceptable] get; set; }
}
[NonInterceptable]
public class Bar
{
[FoobarInterceptor]
public virtual void M() { }
[FoobarInterceptor]
public virtual object? P { get; set; }
}