如何使用 Ninject 将拦截器添加到特定方法
How to add an interceptor to a particular method using Ninject
为了用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 容器。
I would prefer full control of method execution
虽然 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());
为了用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 容器。
I would prefer full control of method execution
虽然 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());