使用参数的Ninject方法级拦截



我在拦截教程中注意到,您可以针对方法并拦截它。即。

 Kernel.Bind<Foo>().ToSelf();
 Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(), invocation => {} );

文档/教程在您试图拦截的方法具有参数的情况下,即可涵盖该执行的操作。

 Kernel.Bind<Foo>().ToSelf();
 Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(**param goes here**), invocation => {} );

在绑定时,我无法访问参数,所以我想知道我是否以错误的方式操作?

编辑

工作示例

我认为您正在误解会发生什么。您的Foo对象被包含拦截器的装饰器代替。这是一个简单的例子:

public class FooDecorator : Foo
{
    private readonly Foo decorated;
    public FooDecorator(Foo foo) { this.decorated = foo; }
    public void ThrowsAnError(object param1, int param2)
    {
        // calls the decorated instance with supplied parameters
        this.decorated.ThrowsAnError(param1, param2);
    }
}

换句话说,称为foo时提供的参数将传递到装饰的实例。

随着拦截,这都是间接的(较慢),但概念是相同的。我必须承认,我不熟悉NInike拦截,但是invocation对象上可能有Proceed方法。换句话说,您应该做这样的事情:

Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(),
    invocation =>
    {
        try
        {
            // calls the decorated instance with supplied parameters
            invocation.Proceed();
        }
        catch (Exception ex)
        {
            Kernel.Get<ILogger>().Log(ex);
        }
    } );

update

我假设InterceptReplace<T>方法的第一个参数不是委托,而是表达树,例如Expression<Action<T>>。实际上,该方法未调用,但是可以分析以找出要拦截的方法。换句话说,由于该方法从未被调用,因此您可以提供任何参数。诀窍是让C#编译器知道要使用哪种方法过载(如果有)。是否提供垃圾都没关系。当两个参数都是参考类型时,这可能会起作用:

Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null),

相关内容

  • 没有找到相关文章

最新更新