I recently began working on the new version of this blog which will be built with ASP.NET MVC, EPiServer Community and EPiServer CMS. One of the first things I set out to do was to implement a custom controller factory which uses the IoC container StructureMap to resolve dependencies and instantiate controllers. It didn’t take long until I was amazed with how simple it can (see the disclaimer at the end of this post) be. StructureMap and ASP.NET MVC really makes a mean combo!
In my website project I have a controller that looks something like the code below. The relevant part is the constructor.
using System.Web.Mvc; using EPiServer.Common.Sorting; using EPiServer.Community.Blog; using JoelAbrahamsson.Abstractions; namespace JoelAbrahamsson.Web.Controllers { public class HomeController : Controller { BlogHandlerFacade _blogHandlerFacade; public HomeController(BlogHandlerFacade blogHandlerFacade) { _blogHandlerFacade = blogHandlerFacade; } public ActionResult Index() { Blog blog = _blogHandlerFacade.GetBlog(2); EntrySortOrder sortOrder = new EntrySortOrder(EntrySortField.Created, SortingDirection.Descending); return View(blog.GetEntries(1, 10, sortOrder)); } } }
As you can see this controller depends on an instance of the BlogHandlerFacade class. That class is a wrapper around EPiServer Community’s BlogHandler class which contains a bunch of static methods. My facade class contains methods with the same signatures as BlogHandler but instead of being static the methods are virtual instance methods which allows me to decouple my code from BlogHandler. Anyhow, how BlogHandlerFacade works isn’t really the point. The point is that the controller needs an instance of BlogHandlerFacade as a constructor parameter to function properly.
In order to supply a BlogHandlerFacade to the controller, and any other controller that might need one, as well as resolving any other constructor parameters for my controllers I added a reference to StructureMap to my project and created a custom controller factory, StructureMapControllerFactory.
using System; using System.Web.Mvc; using StructureMap; namespace JoelAbrahamsson.Web { public class StructureMapControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(Type controllerType) { return (IController)ObjectFactory.GetInstance(controllerType); } } }
The controller factory only contains a single method, GetControllerInstance. All other methods are inherited from the standard DefaultControllerFactory. The GetControllerInstance method retrieves an instance of the specified controller type from StructureMaps ObjectFactory, casts it to IController and returns it.
The last part that I did was to register the controller factory which I did in global.asax.
protected void Application_Start(Object sender, EventArgs e) { ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory()); }
That’s all there was to it! When my controller is executed the controller factory will populate the constructor parameter and I can ignore that dependency.
This is of course a very simple scenario and the only reason I’m getting away with not doing any registration at all with the IoC container is that the type I’m resolving is a concrete type. Once I’ve read up on StructureMap I will probably realize that I’ve just violated a bunch of best practices and when my application grows more advanced I’m sure I’ll have to do some type registration. But still, it’s pretty damn cool that these few lines of code works!
PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.
Similar articles
- XML sitemap with ASP.NET MVC
- The Open/Closed Principle – A real world example
- Dependency Injection with Page Type Builder 1.2
- Twitter style paging with ASP.NET MVC and jQuery
- Extending ASP.NET MVC Music Store with elasticsearch
- Something to beware of when using EPiAbstractions and an IoC container
- EPiServer and MVC – Retrieving current page using a custom model binder
- EPiMVC – A framework for using EPiServer CMS with ASP.NET MVC
Comments
comments powered by Disqus