gpt4 book ai didi

c# - Ninject 方法级拦截带参数

转载 作者:太空狗 更新时间:2023-10-29 20:31:15 24 4
gpt4 key购买 nike

我在拦截教程中注意到,您可以定位一个方法并拦截它。即

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

文档/教程不包括在您尝试拦截的方法具有参数的情况下该怎么做,即如果 ThrowsAnError 接受一个字符串作为参数。

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

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

编辑

Working example

最佳答案

我认为您误解了发生的事情。你的Foo object 被替换为包含拦截器的装饰器。这是一个简单的例子:

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 时提供的参数将传递给装饰实例。

然而,对于拦截,这有点间接(也更慢),但概念是相同的。我必须承认我不熟悉 Ninject 拦截,但可能有一个 Proceed invocation 上的方法目的。换句话说,你应该这样做:

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);
}
} );

更新

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

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

关于c# - Ninject 方法级拦截带参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13248507/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com