I have a project with several layers - among them the web interface (ASP.NET MVC3) and the end of the service (mostly business logic). The project takes several months, so everything works as expected. Now I'm trying to add a logging aspect to some of the MVC3 controller methods using custom [Log] attributes.
I use Castle Windsor to inject dependencies. To get the logical aspect, I use Castle DynamicProxy via SNAP . Controllers are solved using the WindsorControllerFactory from the useful Krzysztof Koźmic tutorial, but I changed it to see the default interface for the controller (see below).
In my service layer:
[Log(LoggingLevel.Info)] public void Save(MyBusinessDto dto) {
In my IWindsorInstaller web interface for controllers:
private static BasedOnDescriptor FindControllers() { return AllTypes .FromThisAssembly() .BasedOn<IController>() .WithService.DefaultInterface(); }
In my (slightly tuned) WindsorControllerFactory , which is looking for the default controller interface:
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; }
In my controllers:
public class MyBusinessController : MyBusinessControllerBase, IMyBusinessController { [Log(LoggingLevel.Debug)] public ActionResult CreateOrUpdate(MyBusinessFormModel fm) {
All this works fine in a service project, but methods are not intercepted in controllers.
- I confirmed that
WindsorControllerFactory returns proxy controllers. - I confirmed that the controllers have a registered interceptor.
- I confirmed that
MasterProxy in SNAP intercepts the controller, but it only intercepts IController.Execute(RequestContext requestContext) .
How to intercept all controller methods that have my [Log] attribute?
Update 1: I looked at using DynamicProxy directly, not SNAP, but this is secondary to make it work for controllers as well.
Update 2 + 4: It looks like SNAP is missing from github back to github .
Update 3: This is what I see in the Visual Studio debugger when hacking the WindsorControllerFactory (see above). The checked controller variable is what MVC returns, and it is really proxied.
controller {Castle.Proxies.IMyBusinessControllerProxy}__interceptors {Castle.DynamicProxy.IInterceptor [1]}__target {My.Business.Web.Controllers.MyBusinessController}service {Castle.Proxies.IMyBusinessServiceProxy}- (other contructor injections)
MyInjectedProperty {My.Business.Useful.MyOtherType}