あなたは何が起こるか誤解していると思います。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が呼び出されたときに提供されるパラメーターは、装飾されたインスタンスに渡されます。
ただし、インターセプトを使用すると、これはすべて少し間接的(そして低速)になりますが、概念は同じです。私は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>
メソッドの最初の引数はデリゲートではなく、などの式ツリーであると想定していExpression<Action<T>>
ます。このメソッドは実際には呼び出されませんが、インターセプトするメソッドを見つけるために分析されます。つまり、メソッドが呼び出されることはないため、任意の引数を指定するだけで済みます。秘訣は、使用するメソッドのオーバーロード(存在する場合)をC#コンパイラに知らせることです。ごみを出すかどうかは関係ありません。両方の引数が参照型の場合、これはおそらく機能します。
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null),