如何使用 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 容器。

如何使用 Ninject 将拦截器添加到特定方法

我更喜欢完全控制方法执行

虽然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());