У меня есть проект с несколькими уровнями - среди них веб-интерфейс (ASP.NET MVC3) и сервисный интерфейс (в основном бизнес-логика).Проекту несколько месяцев, поэтому все работает как положено.Теперь я пытаюсь добавить аспект ведения журнала в некоторые методы контроллера MVC3, используя пользовательские атрибуты [Log]
.
Я использую Castle Windsor для внедрения зависимостей.Чтобы получить аспект ведения журнала, я использую Castle DynamicProxy - SNAP .Разрешение контроллеров осуществляется с помощью WindsorControllerFactory
из полезного руководства Кшиштофа Кочича, но я изменил его, чтобы найти интерфейс контроллера по умолчанию (см. Ниже).
На моем уровне обслуживания:
[Log(LoggingLevel.Info)]
public void Save(MyBusinessDto dto)
{
// business logic and other checks
this.repository.Save(mbo);
}
В моем веб-интерфейсе IWindsorInstaller
для контроллеров:
private static BasedOnDescriptor FindControllers()
{
return AllTypes
.FromThisAssembly()
.BasedOn<IController>()
.WithService.DefaultInterface();
}
В моем (слегка настроенном) WindsorControllerFactory
, который ищет интерфейс по умолчанию дляконтроллер:
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format(Error404, requestContext.HttpContext.Request.Path));
}
string controllerName = controllerType.Name;
string defaultInterfaceName = 'I' + controllerName;
Type defaultInterface = controllerType.GetInterface(defaultInterfaceName);
object controller = this.kernel.Resolve(defaultInterface);
return (IController)controller;
}
В моих контроллерах:
public class MyBusinessController : MyBusinessControllerBase, IMyBusinessController
{
[Log(LoggingLevel.Debug)]
public ActionResult CreateOrUpdate(MyBusinessFormModel fm)
{
// Convert form model to data transfer object,
// perform validation and other checks
this.service.Save(dto);
return View(fm);
}
}
Все это прекрасно работает в сервисном проекте, но в контроллерах методы не перехватываются.
- Я подтвердил, что
WindsorControllerFactory
возвращает прокси-контроллеры. - Я подтвердил, что контроллеры зарегистрировали перехватчик.
- Я подтвердил, что
MasterProxy
в SNAP перехватываетконтроллер - но он только перехватывает IController.Execute(RequestContext requestContext)
.
Как я могу перехватить все методы контроллера, которые имеют мой атрибут [Log]
?
Обновление 1:Я рассмотрел использование DynamicProxy напрямую вместо SNAP, но это вторично по отношению к тому, чтобы заставить его работать и для контроллеров.
Обновление 2 + 4: кажется, что SNAP отсутствует в github обратноgithub .
Обновление 3: это то, что я вижу в отладчике Visual Studio при взломе WindsorControllerFactory
(см. выше).Проверенная переменная controller
- это то, что возвращается в MVC, и она действительно проксируется.
controller
{Castle.Proxies.IMyBusinessControllerProxy} __interceptors
{Castle.DynamicProxy.IInterceptor [1]} __target
{My.Business.Web.Controllers.MyBusinessController} service
{Castle.Proxies.IMyBusinessServiceProxy} - (другие инъекции в конструктор)
MyInjectedProperty
{My.Business.Useful.MyOtherType}