2014-09-25 8 views
0

У меня есть проект MVC 4 и Ninject 3 все подключены.. Перехват контроллеров MVC с Ninject

Теперь я хочу обработать перехват методов моего MVC-контроллера.

Если добавить это:

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

это своего рода работает (хотя мои собственные методы не перехватили, но вместо этого я получаю BeginExecute, EndExecute и Dispose методы перехваченных базового класса Controller). Но скажем, сейчас все в порядке.

Если я хочу, чтобы перехватить конкретный метод на моем HomeController так:

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

Это просто не работает. Перехват никогда не срабатывает.

С другой стороны, если я использую тот же метод перехвата в каком-то классе простой службы в моем проекте, то он работает. Похоже, что только методы контроллера не могут быть перехвачены.

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

^Это работает.

Есть ли у кого-нибудь идеи, что мне делать?

PS. Я использую NinjectWebCommon с WebActivators:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(TT.NinjectWebCommon), "Start")] 
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(TT.NinjectWebCommon), "Stop")] 

ответ

0

Ninject расширения перехвата, который использует либо Линьф или замокли Динамический Прокси-сервер для перехвата только может перехватывать методы, которые являются виртуальными или в случае интерфейса прокси-сервера, все методами интерфейс. Вы должны взглянуть на this прокси-сервер динамического прокси-сервера «виды прокси-объектов».

Однако дальнейшее ограничение состоит в том, что только методы перехватываются, которые называются внешними. Если метод вызван объектом, он сам, перехват не работает.

Например, если вы хотите иметь:

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

    public virtual void ReallyDoIt() 
    { 

    } 
} 

Foo f; 
f.Bar(); 

И вы kernel.Get<Foo>().Bar(); прокси перехватит Bar() но неReallyDoIt().

Как вы его описали, я полагаю, что ваш базовый класс контроллера вызывает doSomethingOnEnter и doSomethingOnExit методов. Как указано выше, это не сработает.

+1

Я думаю, что уловкой здесь является применение перехватчика на «IController» вместо какого-либо конкретного контроллера. Возможно, вам понадобится внедрить и зарегистрировать фабрику пользовательских контроллеров, чтобы потянуть ее. – Steven