0

I have MVC 4 project and Ninject 3 all wired up.

Now I want to handle interception on my MVC Controller methods.

If I add this:

kernel.Bind<TT.Controllers.HomeController>().ToSelf().Intercept().With<TT.Interceptors.LoggingInterceptor>();

it kinda works (even though my own methods are not intercepted, but instead I get BeginExecute, EndExecute and Dispose methods intercepted of base Controller class). But let's say that is ok for now.

If I want to intercept specific method on my HomeController like this:

kernel.InterceptAround<TT.Controllers.HomeController>(
                c => c.Index(),
                invocation => doSomethingOnEnter(invocation),
                invocation => doSomethingOnExit(invocation)
                );

It simply does not work. Interception is never fired.

On the other hand, if I use the same method interception on some plain service class in my project then it works. Seems like only Controller methods are having problem being intercepted.

kernel.InterceptAround<UrlService>(
                    c => c.DoSomething(),
                    invocation => doSomethingOnEnter(invocation),
                    invocation => doSomethingOnExit(invocation)
                    );

^This works.

Does anyone have any idea on what should I do?

PS. I am using NinjectWebCommon with WebActivators:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(TT.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(TT.NinjectWebCommon), "Stop")]
Goran
  • 1,807
  • 7
  • 27
  • 41

1 Answers1

0

The ninject interception extension, which uses either Linfu or Castle Dynamic Proxy for interception, only can intercept methods that are virtual or in case of an interface proxy, all methods of the interface. You should have a look at this castle dynamic proxy "kinds of proxy objects" overview.

However, a further restriction is, that only methods are intercepted which are called externaly. If the method is called by the object it self, interception does not work.

For example, if you'd have:

public class Foo
{
    public virtual void Bar()
    {
        this.ReallyDoIt();
    }

    public virtual void ReallyDoIt()
    {

    }
}

Foo f;
f.Bar();

And you do kernel.Get<Foo>().Bar(); the proxy would intercept Bar() but not ReallyDoIt().

As you describe it, i take it that your base controller class is calling doSomethingOnEnter and doSomethingOnExit methods. As stated before, this can't work.

BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • 1
    I think the trick here is to apply the interceptor on `IController` instead of any concrete controller. You might need to implement and register a custom controller factory to pull this of. – Steven Sep 29 '14 at 17:24