I think you are misunderstanding what happens. Your Foo
object is replaced with an decorator that contains the interceptor. Here is a simplistic example:
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);
}
}
In other words, the parameters that are supplied when the resolved Foo is called, will be passed on to the decorated instance.
With interception however, this is all a bit more indirect (and slower), but the concept is the same. I must admit that I'm not familiar with Ninject interception, but there is probably a Proceed
method on the invocation
object. In other words, you should do something like this:
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
I assume that the first argument of the InterceptReplace<T>
method is not an delegate, but an expression tree, such as Expression<Action<T>>
. This method is in fact not called, but it is analyzed to find out which method to intercept. In other words, since the method is never called, you can just supply any argument you which. The trick is to let the C# compiler know which method overload (if any) to use. It doesn't matter if you supply rubbish. When both arguments are reference types, this will probably work:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null),
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(),...);
would require arguments to be entered in there, otherwise it wont compile as ThrowsAnError requires N arguments right, in your instance you would have to bind like so I think.Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(somehowSatisfyParam1, somehowSatisfyParam2), ...);
I could be wrong though. – Haileyhailfellowwellmet