Ninject Method level interception with parameters

I noticed in interception tutorials that you can target a method and intercept it. I.e.

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

The documentation / tutorial does not describe what to do if the method you are trying to intercept has ie parameters, if ThrowsAnError accepted the string as a parameter.

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

During the binding, I do not have access to the parameters, so I was wondering if I was not mistaken in this?

Edit

Working example

+6
source share
1 answer

I think you do not understand what is happening. Your Foo object is replaced with a decorator containing an interceptor. Here is a simplified 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 provided when the allowed Foo is called will be passed to the decorated instance.

With interception, however, this is all a bit indirect (and slower), but the concept is the same. I must admit that I am not familiar with Ninject interception, but there probably exists a Proceed method for 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 to the InterceptReplace<T> method is not a delegate, but an expression tree, such as Expression<Action<T>> . This method is not actually called, but it is analyzed to find out which method to intercept. In other words, since the method is never called, you can simply specify any argument you want. The trick is to let the C # compiler know which method overloads (if any). It doesn’t matter if you deliver garbage. When both arguments are reference types, this will probably work:

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

All Articles