Click here to Skip to main content
Click here to Skip to main content

How To Use Unity Container In ASP.NET MVC Framework

, 4 Aug 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
The article explains how to use Unity IoC container in ASP.NET MVC Framework.

Introduction

In the past, I wrote a post about How To Use Unity Container In ASP.NET.
In this article, I'm going to show and explain how you can use Unity IoC container in ASP.NET MVC Framework in order to make aspects in our application more decoupled.

Building The Container

As in the previous post, the first thing to do is to build the container itself. I'll use the same method that I used in the previous post in order to persist the Unity container’s state during the application execution. The right place to put the Unity container is as part of the Global.asax file as a property of the current running HTTP application. I'm going to use the same interface that I used in the past which looks like:

public interface IContainerAccessor
{
    IUnityContainer Container { get; }
}

After the building of the interface, implement it in the Global class in the Global.asax file:

public class MvcApplication : HttpApplication, IContainerAccessor
{
    #region Members

    private static IUnityContainer _container;

    #endregion

    #region Properties

    /// <summary>
    /// The Unity container for the current application
    /// </summary>
    public static IUnityContainer Container
    {
        get
        {
            return _container;
        }
    }

    #endregion

    #region IContainerAccessor Members

    /// <summary>
    /// Returns the Unity container of the application 
    /// </summary>
    IUnityContainer IContainerAccessor.Container
    {
        get { return Container; }
    }

    #endregion

    #region Application Events

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        InitContainer();
        ControllerBuilder.Current.SetControllerFactory(typeof(UnityControllerFactory));
    }

    protected void Application_End(object sender, EventArgs e)
    {
        CleanUp();
    }

    #endregion

    #region Methods

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );
    }

    private static void InitContainer()
    {
        if (_container == null)
        {
            _container = new UnityContainer();
        }

        // Register the relevant types for the 
        // container here through classes or configuration
        _container.RegisterType<IMessageService, MessageService>();
    }

    private static void CleanUp()
    {
        if (Container != null)
        {
            Container.Dispose();
        }
    }

    #endregion
}

The implementation is straightforward. You create a getter for the container which is a member of the HTTP application. Also in the application start event, I register all the relevant dependencies in the container and I dispose the container when the application ends.

The Unity Controller Factory

The real and important change with this new implementation of Global.asax is the setting of the controller factory which you will need to supply. The controller factory's responsibility is to instantiate the relevant controller for the incoming HTTP request. You should implement the IControllerFactory interface in order to be able to plug in your factory implementation.
The code for the UnityControllerFactory is as follows:

public class UnityControllerFactory : IControllerFactory
{
    #region IControllerFactory Members

    public IController CreateController
	(RequestContext requestContext, string controllerName)
    {
        IContainerAccessor containerAccessor =
            requestContext.HttpContext.ApplicationInstance as IContainerAccessor;

        Assembly currentAssembly = Assembly.GetExecutingAssembly();
        var controllerTypes = from t in currentAssembly.GetTypes()
                              where t.Name.Contains(controllerName + "Controller")
                              select t;

        if (controllerTypes.Count() > 0)
        {
            return containerAccessor.Container.Resolve
			(controllerTypes.First()) as IController;
        }
        return null;    
    }

    public void ReleaseController(IController controller)
    {
        controller = null;
    }

    #endregion
}

The main thing to do is to implement the CreateController method of the IControllerFactory interface. I use the request context parameter to retrieve the current application instance and from it, I get the Unity container using the interface of IContainerAccessor. I also need to instantiate the relevant controller class which is being done by the Unity container for me.

The container will inject the dependencies in the controller by the Resolve method and we will get the dependency injection functionality that we wanted.

The Class to be Injected

I also wrote a MessageService which is a simple class that returns a message and inherit
from the IMessageService which declares the GetMessage method:

public interface IMessageService
{
    string GetMessage();
}

public class MessageService : IMessageService
{
    #region IMessageService Members

    public string GetMessage()
    {
        return "Hello Controller!";
    }

    #endregion
} 

The Controller

The last piece in this puzzle is the controller class. I implemented the HomeCotroller class with the following code:

[HandleError]
public class HomeController : Controller
{
    #region Members

    [Dependency]
    public IMessageService MessageService { get; set; }        

    #endregion

    #region Actions

    public ActionResult Index()
    {
        ViewData["Message"] = MessageService.GetMessage();
        return View();
    }

    public ActionResult About()
    {
        return View();
    }

    #endregion
}

The UnityControllerFactory will inject the dependency of the MessageService property with the relevant class and it's as simple as that. In order to run this, you'll have to create a new MVC framework application, add the classes I wrote and change the supplied HomeController to the implementation I wrote.

Summary

Let's sum up. I showed an example of how to use Unity container in ASP.NET MVC Framework application. This is a very simple example that will help you to get started with Unity in your MVC web applications.

History

  • 5th August, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gil Fink
Technical Lead sparXys
Israel Israel
Gil Fink is a web development expert and ASP.Net/IIS Microsoft MVP. He is the founder and owner of sparXys. He is currently consulting for various enterprises and companies, where he helps to develop Web and RIA-based solutions. He conducts lectures and workshops for individuals and enterprises who want to specialize in infrastructure and web development. He is also co-author of several Microsoft Official Courses (MOCs) and training kits, co-author of "Pro Single Page Application Development" book (Apress) and the founder of Front-End.IL Meetup. You can read his publications at his website: http://www.gilfink.net
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
QuestionGreat article ,Gil [modified] PinmemberShai Aharoni16-Jun-14 21:34 
GeneralMy vote of 2 [modified] Pinmemberyorro4-Dec-13 1:47 
GeneralMy vote of 5 Pinmemberjijinjnc23-Aug-11 0:20 
It is Excel
lent and very useful
QuestionWhat if you place UnityControllerFactory somewhere else? Pinmemberjszczur6-Aug-10 0:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 5 Aug 2010
Article Copyright 2010 by Gil Fink
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid