要使用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容器。
答案 0 :(得分:3)
我更希望完全控制方法执行
虽然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);
以下是扩展方法的另一个例子(基于Alexei Levenkov评论):
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());