ASP.NET MVC with Windsor – programmatic controller registration

March 28, 2009 at 11:29 AMAndre Loker

Although I’m a loyal MonoRail user, I’m playing with ASP.NET MVC a bit sometimes if time permits. One of the first things I wanted to do is using an IoC container such as Windsor to resolve controllers. ASP.NET MVC was built with extensibility in mind, so that’s not much of a problem, and it has been written about, for example by Matt Hall.

The problem is that the articles I read use the Windsor XML configuration for this. Frankly, I don’t like to configure my IoC container using XML if I don’t have to. Its syntax is pretty verbose and honestly I don’t need the controllers to be configured externally. Therefore, I prefer to use programmatic registration. Windsor has such a sweet registration API, you got to love it.

Alright, so what do you have to do to make programmatically registered controllers available to ASP.NET MVC?

Step 1 – create the container instance

This is easy: in the Application_Start event create the WindsorContainer and store it in a static(!) field. It has to be static, because more than one instance of the HttpApplication can potentially be created.

 

   1: public class MvcApplication : System.Web.HttpApplication {
   2:   static IWindsorContainer container;
   3:  
   4:   protected void Application_Start() {
   5:     CreateWindsorContainer();
   6:     RegisterRoutes(RouteTable.Routes); // has been there before!
   7:   }
   8:  
   9:   static void CreateWindsorContainer() {
  10:     container = new WindsorContainer();
  11:   }
  12: }

Did I mention that the container field needs to be static?

Step 2 – register controllers

This is where the nice API of Windsor comes into play. Extend the application as follows:

   1: public class MvcApplication : System.Web.HttpApplication{
   2:   ...
   3:  
   4:   protected void Application_Start() {
   5:     CreateWindsorContainer();
   6:     RegisterRoutes(RouteTable.Routes);
   7:     RegisterControllers(); // added
   8:   }
   9:  
  10:   ...
  11:  
  12:   static void RegisterControllers() {
  13:     container.Register(
  14:       AllTypes
  15:         .FromAssembly(Assembly.GetExecutingAssembly())
  16:         .BasedOn<IController>()        
  17:     );
  18:   }
  19: }

This is simple, isn’t it? No per-controller-entry in some XML file, just a simple piece of code.

Step 3 – create your own controller factory

To create the controller instances, ASP.NET MVC uses an object that implement IControllerFactory. So all we need to do is roll our own controller factory that uses Windsor and tell ASP.NET MVC to use that.

OK, so here’s our controller factory:

   1: public class WindsorControllerFactory : IControllerFactory {
   2:  
   3:   readonly IWindsorContainer container;
   4:  
   5:   public WindsorControllerFactory(IWindsorContainer container) {
   6:     this.container = container;
   7:   }
   8:  
   9:   public IController CreateController(RequestContext requestContext, string controllerName) {
  10:     var componentName = GetComponentNameFromControllerName(controllerName);
  11:     return container.Resolve<IController>(componentName);
  12:   }
  13:  
  14:   public void ReleaseController(IController controller) {
  15:     container.Release(controller);
  16:   }
  17:  
  18:   /// <summary>
  19:   /// Maps from a simple controller name to the name of the component
  20:   /// that implements the controller.
  21:   /// </summary>
  22:   /// <param name="controllerName">Name of the controller.</param>
  23:   /// <returns>Name of the controller component.</returns>
  24:   static string GetComponentNameFromControllerName(string controllerName) {
  25:     var controllerNamespace = typeof(HomeController).Namespace;
  26:     return string.Format("{0}.{1}Controller", controllerNamespace, controllerName);
  27:   }
  28: }

Nothing fancy here: first, we’ll need the windsor container instance, so we pass it as a constructor dependency. CreateController and ReleaseController are the two methods of IControllerFactory – their purpose should be self-explanatory. GetComponentNameFromControllerName maybe needs some further explanation. ASP.NET MVC will ask for controllers by their simple name, that is “Home” or “About” etc. However, by the way we registered the controller components Windsor knows them by their full type name, e.g. “MyApplication.Controllers.HomeController” and “MyApplication.Controllers.AboutController”. GetComponentNameFromControllerName simply converts from the simple controller name to the full component name.

Step 4 – tell ASP.NET MVC to use our controller factory

The last step is to tell ASP.NET MVC to actually use our IControllerFactory implementation instead of the default one. Conceptually this is easy, we only need to call ControllerBuilder.Current.SetControllerFactory and pass it either the type of our IControllerFactory implementation or an instance. But let’s not be too quick here and try to keep our application as DI-ish as possible. Here’s how I’d set the controller factory:

   1: public class MvcApplication : System.Web.HttpApplication{
   2:   ...
   3:  
   4:   protected void Application_Start() {
   5:     CreateWindsorContainer();
   6:     RegisterRoutes(RouteTable.Routes);
   7:     RegisterControllers();
   8:     RegisterControllerFactory(); // new
   9:   }
  10:   
  11:   void RegisterControllerFactory() {
  12:     container.Register(
  13:       Component
  14:         .For<IControllerFactory>()
  15:         .ImplementedBy<WindsorControllerFactory>()
  16:         .LifeStyle.Singleton
  17:       );
  18:     var controllerFactory = container.Resolve<IControllerFactory>();
  19:     ControllerBuilder.Current.SetControllerFactory(controllerFactory);
  20:   }
  21:  
  22:   static void CreateWindsorContainer() {
  23:     container = new WindsorContainer();
  24:     // new: register the container with itself 
  25:     //      to be able to resolve the dependency in the ctor
  26:     //      of WindsorControllerFactory
  27:     container.Register(
  28:       Component
  29:         .For<IWindsorContainer>()
  30:         .Instance(container)
  31:       );
  32:   }  
  33:  
  34:   ...
  35: }

You see, instead of new-ing an instance of WIndsorControllerFactory we register it as a singleton component and resolve it. Also note that we needed to register the Windsor container with itself to have the constructor dependency resolved.

Finally, here’s the complete source code of the global application class so far:

   1: public class MvcApplication : System.Web.HttpApplication {
   2:   static IWindsorContainer container;
   3:  
   4:   public static void RegisterRoutes(RouteCollection routes) {
   5:     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   6:  
   7:     routes.MapRoute(
   8:       "Default", // Route name
   9:       "{controller}/{action}/{id}", // URL with parameters
  10:       new { controller = "Home", action = "Index", id = "" } // Parameter defaults
  11:       );
  12:   }
  13:  
  14:   protected void Application_Start() {
  15:     CreateWindsorContainer();
  16:     RegisterRoutes(RouteTable.Routes);
  17:     RegisterControllers();
  18:     RegisterControllerFactory();
  19:   }
  20:  
  21:   static void CreateWindsorContainer() {
  22:     container = new WindsorContainer();
  23:     container.Register(
  24:       Component
  25:         .For<IWindsorContainer>()
  26:         .Instance(container)
  27:       );
  28:   }
  29:  
  30:   static void RegisterControllers() {
  31:     container.Register(
  32:       AllTypes
  33:         .FromAssembly(Assembly.GetExecutingAssembly())
  34:         .BasedOn<IController>()
  35:       );
  36:   }
  37:  
  38:   static void RegisterControllerFactory() {
  39:     container.Register(
  40:       Component
  41:         .For<IControllerFactory>()
  42:         .ImplementedBy<WindsorControllerFactory>()
  43:         .LifeStyle.Singleton
  44:       );
  45:     var controllerFactory = container.Resolve<IControllerFactory>();
  46:     ControllerBuilder.Current.SetControllerFactory(controllerFactory);
  47:   }
  48: }

Controller names and component names revisited

As you saw in step 3, we need to map the controller names to component names. This doesn’t take much effort and is my preferred way of handling this. But of course, you can already register the controller components with the respective controller names in the first place if you like. Just change the controller registration to something like this:

   1: static void RegisterControllers() {
   2:   container.Register(
   3:     AllTypes
   4:       .FromAssembly(Assembly.GetExecutingAssembly())
   5:       .BasedOn<IController>()
   6:       // modify the name with which the component is registered:
   7:       .Configure(component => component.Named(ControllerNameFromType(component.Implementation)))
   8:     );
   9: }
  10:  
  11: static string ControllerNameFromType(Type implementation) {
  12:   const string ControllerSuffix = "Controller";
  13:   var name = implementation.Name;
  14:   Debug.Assert(name.EndsWith(ControllerSuffix));
  15:   return name.Substring(0, name.Length - ControllerSuffix.Length);
  16: }

If you do this, you can remove the GetComponentNameFromControllerName method and simplify the implementation of IControllerFactory.CreateController to this:

   1: public IController CreateController(RequestContext requestContext, 
   2:                                     string controllerName) {
   3:   return container.Resolve<IController>(controllerName);
   4: }

Which version you choose is more or less a matter of taste. If you keep the full type name as the component’s name you reduce the chance for name clashes. However, if you register the components using the controller name creating the controller is slightly simpler.

More simplifications

You can even simplify the controller factory a bit if you inherit from DefaultControllerFactory instead of implementing IControllerFactory. Because DefaultControllerFactory will resolve the correct component type for you, you can simply override GetControllerInstance instead of implementing CreateController:

   1: public class WindsorControllerFactory : DefaultControllerFactory {
   2:   readonly IWindsorContainer container;
   3:  
   4:   public WindsorControllerFactory(IWindsorContainer container) {
   5:     this.container = container;
   6:   }
   7:  
   8:   protected override IController GetControllerInstance(System.Type controllerType) {
   9:     return container.Resolve(controllerType) as IController;
  10:   }
  11:  
  12:   public override void ReleaseController(IController controller) {
  13:     container.Release(controller);
  14:   }
  15: }

If you need to change the way that the controller name is mapped to a component type, you can also override GetControllerType.

MVC Contrib

As far as I know Windsor integration is also part of the MVC Contrib project. I haven’t looked into it, so bear with me if this article doubles existing code!

Posted in: ASP.NET | Castle

Tags: , , ,

Simple AOP: integrating interceptors into Windsor

February 20, 2009 at 3:47 PMAndre Loker

Aspect oriented programming (AOP) allows us to keep implement different concerns in isolation. In this article series I’ll describe ways to make use of AOP without much hassle. In the previous article of this serious we learned how to intercept method invocations using DynamicProxy2 and IInterceptors. However, we had to create the proxy instances manually. If you use Castle Windsor you can let the IoC container create the proxies and inject the interceptors.

I assume that you have used Castle Windsor or a different IoC container before. If not, check why you should use dependency injection.

Luckily Windsor integration of IInterceptors is a snap. In fact, you don’t have to add anything, it’s already been built in, because it has proven to be very useful. Because Windsor controls the instantiation of the registered components it was a logical consequence to add optional proxy creation and interface injection into that process. The Castle people are know what they do!

Basically, Windsor offers three ways to define interceptors that you want it to inject into components, ranging from rather static to fully dynamic.

Static injection with attributes

If all you want is the separation of concerns that injectors offer you and know which classes those aspects need to be applied to you can simply use the InterceptorAttribute.

Let’s start with a simple service interface and its implementation:

   1: public interface IService {
   2:     void DoSomething();
   3: }
   4:  
   5: public class Service : IService {
   6:     public void DoSomething() {
   7:         Console.WriteLine("Doing something");
   8:         throw new InvalidOperationException("Some exception thrown in DoSomething");
   9:     }
  10: }

And here’s the code that sets up Windsor for this service and creates an instance.

   1: var container = new WindsorContainer();
   2: container.Register(
   3:     Component.For<IService>().ImplementedBy<Service>()
   4: );
   5:  
   6: var service = container.Resolve<IService>();
   7: service.DoSomething();

As expected, running this piece of code will print “Doing something” and than fail with an uncaught exception. Now let’s say we want to add an aspect to the code that – in this simple case – prints a message to the console whenever an intercepted method throws an exception. Here’s the simple exception handling aspect from the previous article, which catches exception, prints an information message and optionally re-throws it.

   1: public class ExceptionAspect : IInterceptor {
   2:     public bool EatAll { get; set; }
   3:  
   4:     public void Intercept(IInvocation invocation) {
   5:         try {
   6:             invocation.Proceed();
   7:         } catch (Exception e) {
   8:             Console.WriteLine("{0} caught: {1}", e.GetType(), e.Message);
   9:             if (!EatAll) {
  10:                 throw;
  11:             }
  12:         }
  13:     }
  14: }

 

 

Two automatically inject this aspect into the Service component you only need to add two minor modifications:

1. Register the ExceptionAdvice as a component:

   1: container.Register(
   2:     Component.For<ExceptionAspect>()
   3:     .Parameters(Parameter.ForKey("EatAll").Eq("true"))
   4: );

 

2. Add the Castle.Core.InterceptorAttribute to the Service component:

   1: [Interceptor(typeof(ExceptionAspect))]
   2: public class Service : IService{
   3:     public void DoSomething() {
   4:         Console.WriteLine("Doing something");
   5:         throw new InvalidOperationException("Some exception thrown in DoSomething");
   6:     }
   7: }

This will tell Windsor to automatically create a proxy for the Service component and inject the interceptor of the given type (ExceptionAspect). Running the code now leads to the expected output:

image

Instead of a type you can also provide the key of a component to the InterceptorAttribute.

Simple dynamic injection

 

 

 

If you cannot or don’t want to use attributes – e.g. because you need to disable or enable certain aspects during configuration time – you can of course configure the Windsor container manually.

Let’s add a second aspect, namely a simple logging aspect that prints a message before and after the execution of intercepted methods. This is what our aspect looks like:

   1: public class LoggingAspect : IInterceptor {
   2:     public void Intercept(IInvocation invocation) {
   3:         Console.WriteLine("SomeInterceptor: Before method");
   4:         try {
   5:             invocation.Proceed();
   6:         } finally {
   7:             Console.WriteLine("SomeInterceptor: After method");
   8:         }
   9:     }
  10: }

Now we need to tell Windsor to inject the LoggingAspect into our Service. As with the ExceptionAspect we need to register the advice as a component:

   1: container.Register( Component.For<LoggingAspect>() );

Now we only need to change the registration of the service to inlcude the given aspect:

   1: container.Register(
   2:     Component
   3:     .For<IService>()
   4:     .ImplementedBy<Service>()
   5:     .Interceptors(InterceptorReference.ForType<LoggingAspect>()).Anywhere
   6: );

 

The only change is shown in line 5. The Interceptors() method expects an array of interceptors to apply to the component, Anywhere tells Windsor that we are not interested in the order in which multiple interceptors are applied (see below).

Running the application now yields:

image

 

If you configure the container in source code as shown above you can decide at configuration time which interceptors to inject. Of course, the interceptors can also be configured using an external XML file for full configurability.

If you configure multiple interceptors sometimes the order in which they are applied does matter. For example, assume you have an interceptor that caches method results and another one that secures the method for authorized access. In this case you will want the security interceptor to be applied before the caching interceptor, otherwise unauthorized user might see cached values that they are not allowed to see.  Windsor allows you to explicitly state the relative or absolute order of the configured interceptors.

  • ...Interceptors(interceptors).First
    The defined interceptors are prepended to the current list of interceptors.
  • ...Interceptors(interceptors).Last
    The defined interceptors are append to the current list of interceptors.
  • ...Interceptors(interceptors).AtIndex(x)
    The defined interceptors are inserted at the given index of the current list of interceptors.
  • ...Interceptors(interceptors).Anywhere 
    You don’t care where the interceptors are added.

Fully dynamic injection

You can even go one step further. Instead of defining the interceptors explicitly for the different components, Windsor allows you to install a hook that allows you to define the interceptors for each component on the fly during creation.

You can install that hook by implementing the interface IModelnterceptorsSelector which exposes two methods:

   1: public interface IModelInterceptorsSelector {
   2:     bool HasInterceptors(ComponentModel model);
   3:     InterceptorReference[] SelectInterceptors(ComponentModel model);
   4: }

Before a component is activated, Windsor calls HasInterceptor with the component model. If it returns true Windsor will invoke SelectInterceptors to request the actual interceptor references.

As an exammple, we’ll use another interceptor – TransactionAspect – that is injected with an IModelInterceptorSelector. First, here’s the interceptor:

   1: public class TransactionAspect : IInterceptor {
   2:     public void Intercept(IInvocation invocation) {
   3:         try {
   4:             Console.WriteLine("Opening transaction");
   5:             invocation.Proceed();
   6:             Console.WriteLine("Commit");
   7:         } catch (Exception e) {
   8:             Console.WriteLine("Rollback");
   9:             throw;
  10:         }
  11:     }
  12: }

And here’s our implementation of the IModelInterceptorsSelector:

   1: public class MyInterceptorSelector : IModelInterceptorsSelector {
   2:     public bool HasInterceptors(ComponentModel model) {
   3:         return typeof(TransactionAspect) != model.Implementation &&
   4:             model.Implementation.Namespace.StartsWith("SimpleAopWindsor");
   5:     }
   6:  
   7:     public InterceptorReference[] SelectInterceptors(ComponentModel model) {
   8:         return new[] { InterceptorReference.ForType<TransactionAspect>() };
   9:     }        
  10: }

As you see there’s nothing fancy going on here. HasInterceptors returns true for types in the SimpleAopWindsor namespace that are not TransactionAspect. The check for TransactionAspect is required in this specific case to prevent infinite recursion – otherwise, the TransactionAspect interceptor would be applied to itself.

SelectInterceptors simply returns an array of InterceptorReferences: in this case it contains only one element, ie. a reference to TransactionAspect.

Of course, we need to register the TransactionAspect as a component in Windsor:

   1: container.Register(
   2:     Component.For<TransactionAspect>()                
   3: );

And finally, we need to tell Windsor to use our interceptors selector.

   1: container.Kernel.ProxyFactory.AddInterceptorSelector(
   2:     new MyInterceptorSelector()
   3: );

If we run the application now we’ll see this:

image

What’s important here is the fact that our LoggingAspect and ExceptionAspect seem to be gone. This is important: if IModelInterceptorsSelector.SelectInterceptors returns a non-null array, only those interceptor will be used. Interceptors configured using one of the previously described methods (attributes or registration) will be ignored. If we want those interceptors to be applied as well our IModelnterceptorsSelector needs to return those references explicitly, eg. like this:

   1: public InterceptorReference[] SelectInterceptors(ComponentModel model) {
   2:     var interceptors = new List<InterceptorReference>(model.Interceptors.Count + 1);
   3:     // add all interceptors configured otherwise
   4:     foreach (InterceptorReference inter in model.Interceptors) {
   5:         interceptors.Add(inter);
   6:     }
   7:     // add an additional interceptor
   8:     interceptors.Add(InterceptorReference.ForType<TransactionAspect>());
   9:     
  10:     return interceptors.ToArray();
  11: }

Now our application uses all interceptors:

image

Conclusion

As you’ve seen there are many different ways to inject inspectors into components in a Windsor container, ranging from static definition of inspectors using attributes to fully dynamic injection using IModelInterceptorsSelector.

What’s missing in comparison toclassic” AOP frameworks such as AspectJ? Pointcuts of course! With IModelInterceptorsSelector we are able to choose which types get interceptors applied, but those interceptors intercept every method of the target. We’d like to be able to define something similar to pointcuts to select the methods that get intercepted. And that’s what’s the next article in this series will be about. Stay tuned!

Souce code for this article: SimpleAopWindsor.zip (600.79 kb)

Previous articles:

Posted in: C# | Castle | Patterns

Tags: , ,

MonoRail and Windsor integration

May 18, 2008 at 9:00 PMAndre Loker

Although the procedure of enabling Windsor Container integration is explained quite well in the documentation, I ran into some trouble today. As required by the Windsor integration I made my HttpApplication instance implement IContainerAccessor, created a WindsorContainer instance in Application_Start and returned that instance in the Container property. Still the MonoRail runtime was complaining:

The container seems to be unavailable in your HttpApplication subclass

What went wrong? The problem was that the IWindsorContainer field in the HttpApplication was not static. As described in my previous post (which I only wrote just because of that problem) multiple instances of HttpApplication can be created by the ASP.NET runtime to serve multiple requests at once. As a consequence only the first instance of HttpApplication that was created had a valid container assigned to its field. The first subsequent request found only a null value and raised the exception mentioned above.

Register IContainerAccessor in Windsor

If you want to register your HttpApplication as a IContainerAccessor in Windsor I'd recommend something along this line:

   1: public class ContainerAccessor : IContainerAccessor {
   2:     public IWindsorContainer Container {
   3:         get {
   4:             // lookup container accessor 
   5:             return WindsorContainerAccessorUtil.ObtainContainer();
   6:         }
   7:     }
   8:  
   9:     public static void RegisterAtContainer(IWindsorContainer container){
  10:         container.AddComponentLifeStyle<IContainerAccessor, ContainerAccessor>(LifestyleType.Singleton);
  11:     }
  12: }

Of course you can always just register the container on itself to have it injected into components.

Posted in: Castle

Tags: , ,

Access to MonoRail service instances

May 6, 2008 at 10:18 PMAndre Loker

In my current MonoRail based project - which is in fact my first MonoRail project - I needed access to some of the services provided by the MonoRail container, for example, IEmailTemplateService and IEmailSender. Furthermore the MonoRail app had Windsor Integration enabled, so I wanted them to be injected into the client component by the Windsor IoC container. Unfortunately, the services are not registered as components at the Windsor container.

Luckily, I was pointed at the solution (e.g. here and here) by the kind users of the Castle Project Users mailing list. The key is to let your HttpApplication class implement IMonoRailContainerEvents, which will provide you with a IMonoRailContainer instance as soon as it is created and again when it is initialized.

   1: // Implements IContainerAccessor to notify MonoRail that we provide our own IWindsorContainer
   2: // Implements IMonoRailContainerEvents to be notified when the container was created
   3: public class Global : HttpApplication, IContainerAccessor,  IMonoRailContainerEvents {
   4:     private static Container container;
   5:  
   6:     #region IContainerAccessor Members
   7:     public IWindsorContainer WebContainer {
   8:         get { return container; }
   9:     }
  10:     #endregion
  11:  
  12:     #region IMonoRailContainerEvents Members
  13:     public void Initialized(IMonoRailContainer mr){
  14:         // here we register the services as components
  15:         container.Register(
  16:             Component.For<IEmailTemplateService>().Instance(mr.EmailTemplateService),
  17:             Component.For<IEmailSender>().Instance(mr.EmailSender)
  18:             // additional services here...
  19:         );
  20:     }
  21:  
  22:     public void Created(IMonoRailContainer mr){
  23:         // ignore..
  24:     }
  25:     #endregion
  26:  
  27:     protected void Application_Start(object sender, EventArgs e) {
  28:         // create container
  29:         container = new WebContainer();
  30:         container.Init();
  31:     }
  32: }

The important part is the fact that we implement IMonoRailContainerEvents. In the Initialized method, we can than access the service instances of the MonoRail container. The WebContainer class is a class derived from WindsorContainer that handles the Windsor integration for MonoRail.

   1: public class WebContainer : WindsorContainer {
   2:     public WebContainer()
   3:         : base(new XmlInterpreter(new ConfigResource())) {
   4:     }
   5:  
   6:     public void Init() {
   7:         AddFacility("rails", new MonoRailFacility());
   8:     }
   9: }

Simple like that. With all these pieces of code set up, I can now have the services be injected into my components, for example:

   1: public class DefaultMailService : IMailService {
   2:     private const string defaultFrom = "my application <mail@localhost>";
   3:     private const string defaultMailLayout = "Mail.vm";
   4:  
   5:     #region dependencies - Injected by Windsor
   6:     public IEmailTemplateService Templates { get; set; }
   7:     public IEmailSender Sender { get; set; }
   8:     #endregion
   9:  
  10:     #region IMailService Members
  11:     public void SendActivationMail(string name, string email, string ticket) {
  12:         log.InfoFormat("Sending activation mail to {0}", email);
  13:         var msg = Templates.RenderMailMessage("Activate", defaultMailLayout, new {name, ticket});
  14:         msg.To = email;
  15:         msg.From = defaultFrom;
  16:         Sender.Send(msg);
  17:     }
  18:     #endregion
  19: }

Thanks to the guys from the Castle mailing list.

Posted in: Castle | Snippets

Tags: , , , ,