如何使用 Ninject 将拦截器添加到特定方法
本文关键字:添加 方法 何使用 Ninject | 更新日期: 2023-09-27 18:31:05
为了用Ninject拦截一个特定的方法,我这样做:
[MyInterceptor] void MyMethod()
或者这个:
Kernel.InterceptAround<IMyClass>(c => c.MyMethod(), inv => { ... }, inv => { ... });
我想将所有拦截器添加到一个地方,例如(内核配置),并使MyMethod
没有任何属性。然而,这个Kernel.InterceptAround
签名接受Action
反而IInterceptor
看起来很奇怪!我更喜欢完全控制方法执行。
是否可以为没有属性的特定方法(根本不是类型!)添加一个拦截器,可能使用 Ninject 扩展?我的意思是这样的语法:
Kernel.Intercept<IMyClass>(c => c.MyMethod()).With<MyInterceptor>();
在拦截器中按方法名称进行筛选不是一个好的选择。随意建议另一个 DI 容器。
我更喜欢完全控制方法执行
虽然InterceptAround
只允许您指定执行前后发生的情况,但InterceptReplace
可以通过允许您手动调用IInvocation.Proceed
(或根据需要不调用它)来为您提供完全控制权。
下面是一个示例:
创建一个拦截器,如下所示:
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Do before
invocation.Proceed();
//Do after
}
}
然后你可以像这样使用 InterceptReplace
方法:
var my_interceptor = new Interceptor();
Kernel.InterceptReplace<IMyClass>(
c => c.MyMethod(),
inv => my_interceptor.Intercept(inv));
您可以创建扩展方法来帮助您获得您喜欢的不同语法。下面是一个示例:
public static class MyExtentionMethods
{
public static void UseInterceptorFor<T>(
this IKernel kernel,
Expression<Action<T>> methodExpr,
IInterceptor interceptor)
{
kernel.InterceptReplace<T>(methodExpr, inv => interceptor.Intercept(inv));
}
}
这允许您将语法简化为如下所示:
var my_interceptor = new Interceptor();
Kernel.UseInterceptorFor<IMyClass>(
c => c.MyMethod(),
my_interceptor);
这是扩展方法的另一个示例(基于阿列克谢·列文科夫的评论):
public static class MyExtentionMethods
{
public static void UseInterceptorFor<TObject,TInterceptor>(
this IKernel kernel,
Expression<Action<TObject>> methodExpr)
where TInterceptor : IInterceptor
{
var interceptor = kernel.Get<TInterceptor>();
kernel.InterceptReplace<TObject>(methodExpr, inv => interceptor.Intercept(inv));
}
}
这允许您执行以下操作:
Kernel.UseInterceptorFor<IMyClass,Interceptor>(c => c.MyMethod());