Перехват контроллеров.net MVC с помощью Ninject
У меня есть проект MVC 4 и Ninject 3, все подключены.
Теперь я хочу обработать перехват на моих методах контроллера 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")]
1 ответ
Абонентское перехватное расширение, которое использует для перехвата либо Linfu, либо Castle Dynamic Proxy, может перехватывать только виртуальные методы или, в случае прокси интерфейса, все методы интерфейса. Вы должны взглянуть на этот динамический прокси-замок "виды прокси-объектов".
Однако еще одно ограничение заключается в том, что перехватываются только те методы, которые называются внешними. Если метод вызывается самим объектом, перехват не работает.
Например, если бы вы имели:
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
методы. Как было сказано ранее, это не может работать.