ASP.NET MVC Tip: Dependency Injection with Unity Application Block

In my earlier post, I have explained how to use dependency injection pattern in ASP.net MVC application using StructureMap. In this post, I demonstrate how you can use dependency injection pattern using Microsoft’s Unity Application Block (Unity). If you want to develop an ASP.NET MVC application fully with Microsoft stack, you can use Unity Application Block to perform dependency injection.Unity is a cool dependency injection container and I hope that it will become more powerful in the future releases.

Introduction to Unity

Unity is a lightweight, extensible dependency injection container that provides the support for constructor, property, and method call injection. Unity has a service location capability that allows the ASP.NET developer to store or cache the container in the ASP.NET session, application or per Request.

Register Dependencies

Unity provides two methods for registering types and mappings with the container. The RegisterType method registers a type with the container and the RegisterInstance method registers with the container an existing instance of a type.

 

IUnityContainer container = new UnityContainer();            
container.RegisterType<ICategoryRepository, CategoryRepository>();

 

The above code tells the Unity Container that, to inject the instance of CategoryRepository when there is a request for ICategoryRepository and the container will create a new instance of CategoryRepository every time when there is request for ICategoryRepository. The default behavior is for the container to use a transient lifetime manager and the container will not store or cache a reference to the object. If you want singleton behavior for objects, you have to register a LifetimeManager. A lifetime manager controls how stores references to object instances and reused within the container.

 

IUnityContainer container = new UnityContainer();
    container.RegisterType<ICategoryRepository,
       CategoryRepository>(new ContainerControlledLifetimeManager());

 

The above registration specify that any time an instance of ICategoryRepository is requested, you will get back the same instance of CategoryRepository as long as the container is alive. The container will create a new instance at the time of first request and will be use the same instance for the later requests. The ContainerControlledLifeTimeManager class provides the singleton behavior for the container.

You can create your own custom LifetimeManager class derive from LifetimeManager class. The important methods of LifetimeManager class are GetValue that returns the instance, SetValue method store the instance value and RemoveValue method reomove the instance from the container.

public abstract class LifetimeManager : ILifetimePolicy
{
    public abstract object GetValue();
    public abstract void SetValue(object newValue);
    public abstract void RemoveValue();
}

Use Unity with an ASP.NET MVC application

In this tip, I show how you can use the Unity Application Block to perform Dependency Injection within an ASP.NET MVC application.  In this tip, I will show you how to perform constructor injection. Constructor Injection will push dependencies into a concrete class through constructor arguments.

The below code listings show that a controller class and its dependent classes.

 

Listing 1 – CategoryController

 

public class CategoryController : Controller {
       ICategoryService _categoryService = null;

        //Inject instance of CategoryService using construction injection
        public CategoryController(ICategoryService categoryService) {
            _categoryService = categoryService;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult List(int? page) {
            var categories = _categoryService.GetCategories(page ?? 0, 10);
            return View(categories);
        }
    }

Listing 2 – ICategoryService

 public interface ICategoryService {
    PagedList<Category> GetCategories(int pageIndex,int pageSize); 
    }

 

Listing 3 – CategoryService

  public class CategoryService : ICategoryService  {
         ICategoryRepository _repository = null;
        /// <summary>
         /// Creates a CategoryService based on the passed-in repository
        /// </summary>
         /// <param name="repository">An ICategoryRepository</param>
     public CategoryService(ICategoryRepository repository) {
            _repository = repository;
        if (_repository == null)
           throw new 
                 InvalidOperationException("Repository cannot be null");
        }

    public PagedList<Category> GetCategories(int pageIndex,int pageSize) { 
       return _repository.GetCategories().
         ToPagedList<Category>(pageIndex, pageSize); 
        }
    }

Listing 4 – ICategoryRepository

 

public interface ICategoryRepository {
        IQueryable<Category> GetCategories();       
    }

 

Listing 5 – CategoryRepository

public class CategoryRepository : ICategoryRepository  {

       myFinanceData _db;
        public CategoryRepository(myFinanceData data) {            
            _db = data;
            
        }

        /// <summary>
        /// Linq To Sql implementation for Categories
        /// </summary>
        /// <returns>IQueryable of Categories</returns>
        public IQueryable<Category> GetCategories() {

            return from c in _db.DataContext.Categories
                   select new Category {
                       ID=c.ID,
                       Name=c.Name,
                       Description=c.Description,
                       CategoryType = c.CategoryType
                   };

        }
   }

Listing 6 – myFinanceData

public  class myFinanceData
    {
        private myFinanceDataContext dataContext;

        public myFinanceDataContext DataContext {
            get {
                if (dataContext == null) {
                    dataContext = new myFinanceDataContext();
                }

                return dataContext;
            }
        }
    }

Depedencies

The CategoryController has a dependency with ICategoryService. The concrete implementation of ICategoryService, i.e. CategoryService has a dependency with ICategoryRepository. The concrete implementation of ICategoryRepository, i.e. CategoryRepository has a dependency with myFinanceData. When we calling action methods of Category controller, we need to create objects of CategoryService, CategoryRepository and myFinanceData.

The below steps will configure Unity to perform constructor injection in our ASP.NET MVC application.

Step 1 – Add reference for Unity Application Block

Add a reference to Microsoft.Practices.Unity.dll and Microsoft.Practices.ObjectBuilder2.

You can download Unity from http://www.codeplex.com/unity

Step 2 – Custom LifetimeManager class

Unity provides the functionality to specify the location of instance. This functionality is very useful for the ASP.NET applications where we can store or cache the container in the HttpContext, HttpSession or HttpApplication. In this tip, I used to store the container in current HttpContext.  In the below code, I am creating a custom lifetime manager to store container in the current HttpContext.

 

public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable {
        public override object GetValue() {
            return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
        }
        public override void RemoveValue() {
            HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
        }
        public override void SetValue(object newValue) {
            HttpContext.Current.Items[typeof(T).AssemblyQualifiedName]
                = newValue;
        }
        public void Dispose() {
            RemoveValue();
        }

Step 3 – Controller Factory for Unity

public class UnityControllerFactory : DefaultControllerFactory
{
    IUnityContainer container;

    public UnityControllerFactory(IUnityContainer container)
    {
        this.container = container;
    }

    protected override IController GetControllerInstance(Type controllerType)
    {
        try {
            if (controllerType == null)
                throw new ArgumentNullException("controllerType");

            if (!typeof(IController).IsAssignableFrom(controllerType))
                throw new ArgumentException(string.Format(
                    "Type requested is not a controller: {0}",
                    controllerType.Name),
                    "controllerType");
            return container.Resolve(controllerType) as IController;
        }
        catch { return null; }

    }
 }

 

The controller factory is responsible for creating controller instances.We extend the built in default controller factory with our own factory for working Unity with ASP.NET MVC.

 

Step 4 – Register Types and Set Controller Factory

public static class Bootstrapper {

    public static void ConfigureStructureMap() {

        StructureMap.StructureMapConfiguration.AddRegistry(new DBServiceRegistry());
        StructureMap.StructureMapConfiguration.AddRegistry(new DInjRegistry());


        IUnityContainer container = new UnityContainer();
        container.RegisterType<ICategoryRepository,
        CategoryRepository>(new ContainerControlledLifetimeManager());
    }
    public static void ConfigureUnityContainer() {
        IUnityContainer container = new UnityContainer();
        // Registrations
        container.RegisterType<myFinanceData, myFinanceData>
            (new HttpContextLifetimeManager<myFinanceData>());
        container.RegisterType<ICategoryRepository, CategoryRepository>
            (new HttpContextLifetimeManager<ICategoryRepository>());
        container.RegisterType<ICategoryService, CategoryService>
            (new HttpContextLifetimeManager<ICategoryService>());
        ControllerBuilder.Current.SetControllerFactory(
            new myFinance.Web.Controllers.UnityControllerFactory(container));           
    }
}

 

The above Unity configuration specified in the ConfigureUnityContainer method, tells to inject CategoryService when there is a request for ICategoryService. And also inject CategoryRepository when there is a request for ICategoryRepository. The CategoryRepository class has a dependency with myFinanceData. So we configure that inject the instance of myFinanceData when there is request for myFinanceData. The above code also set the controller factory for working with Unity.

 

Step 5 – Modify Global.asax.cs for configure Unity container

 

 protected void Application_Start() {
            RegisterRoutes(RouteTable.Routes);            
            //Configure for Dependecny Injection using Unity
            Bootstrapper.ConfigureUnityContainer();           
            
        }

The above code will set the configuration for the Unity container when our ASP.NET MVC application is started. The Bootstrapper class is specified in the Step 4.

Summary

In this tip, I demonstrated how you can use the Unity Application Block to perform Dependency Injection within an ASP.NET MVC application. The Unity Application Block allows us to develop highly loosely coupled ASP.NET MVC applications using fully with Microsoft stack.

Published Friday, October 24, 2008 8:26 AM by shiju
Filed under: , ,

Comments

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Friday, October 24, 2008 1:21 PM by Chris

Could you also do one of these using Ninject?

http://ninject.org/

One ting I've noticed in Ninject is that you can bind differently at runtime using Attributes. Can you also do this with the others?

-=Chris

# ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Saturday, October 25, 2008 12:02 AM by DotNetKicks.com

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# Reflective Perspective - Chris Alcock &raquo; The Morning Brew #209

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #209

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Monday, October 27, 2008 11:56 AM by Nairb

I built out virtually the exact same structure over the weekend using Unity and with my own HttpRequestLifetimeManager. I am curious about having Unity create and store items that require disposing at the end of the HttpRequest however. Is there a way to ensure that the items are properly disposed of at the end of a request? My code and question with further details are at:

www.codeplex.com/.../View.aspx

I do like your lifetime manager a bit better, so I'll probably use that.

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Monday, October 27, 2008 4:39 PM by PaulBlamire

Nice article, very clear. Thanks

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Monday, October 27, 2008 5:18 PM by Nairb

I built out virtually the exact same structure over the weekend using Unity and with my own HttpRequestLifetimeManager. I am curious about having Unity create and store items that require disposing at the end of the HttpRequest however. Is there a way to ensure that the items are properly disposed of at the end of a request? My code and question with further details are at:

www.codeplex.com/.../View.aspx

I do like your lifetime manager a bit better, so I'll probably use that.

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Tuesday, October 28, 2008 9:32 AM by Corey J Gaudin

Very nice. I did the same type of blog post with ninject if you are interested:

polymorphicview.blogspot.com/.../utilizing-ninject-with-aspnet-mvc.html

Overrall they seem pretty similar, except that Unity doesnt need to utilize Attributes as much.

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Thursday, December 04, 2008 9:15 PM by Berlin Dong

I take a reference form your article to make my ASP.NET MVC application.

I have a normal URL {controller}/{action}, In my actions, I need to use few services (but not using in same time) or some I don't need to use any service.

So, I may a small changes from your guide as below could you please give your comments for my changes.

public static class Bootstrapper {

public static void ConfigureUnityContainer() {

IUnityContainer container = new UnityContainer();

// Registrations

container.RegisterInstance<IUnityContainer>(container);//Changes.

container.RegisterType<myFinanceData, myFinanceData>     (new HttpContextLifetimeManager<myFinanceData>());

container.RegisterType<ICategoryRepository, CategoryRepository>    (new HttpContextLifetimeManager<ICategoryRepository>());

container.RegisterType<ICategoryService, CategoryService>   (new HttpContextLifetimeManager<ICategoryService>());

ControllerBuilder.Current.SetControllerFactory(

   new myFinance.Web.Controllers.UnityControllerFactory(container));          

 }

}

public class CategoryController : Controller {

       IUnityContainer container;

       public CategoryController(IUnityContainer container) {

           this.container= container;

       }

       /// <summary>

       ///

       /// </summary>

       /// <param name="page"></param>

       /// <returns></returns>

       [AcceptVerbs(HttpVerbs.Get)]

       public ActionResult List(int? page) {

       ICategoryService _categoryService = container.Resolve(typeof(ICategoryService)) as ICategoryService ;

           var categories = _categoryService.GetCategories(page ?? 0, 10);

           return View(categories);        }

    }

public ActionResult DisplayXXX() {

       IXXXService _XXXService = container.Resolve(typeof(IXXXService )) as IXXXService ;

           var XXX= _XXXService.GetXXXs(page ?? 0, 10);

           return View(XXX);        }

    }

//No service request.

public ActionResult Hello()

{

 return view();

}

Thanks!

Berlin.

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Monday, December 08, 2008 3:11 PM by Mike

You have a typo for the first example, Service should be Repository.

Could you also do the same article for Autofac?

Thanks!

# ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Saturday, December 27, 2008 9:42 AM by Web Development Community

You are voted (great) - Trackback from Web Development Community

# ASP.NET MVC 1.0 Release Candidate (RC) Released

Tuesday, January 27, 2009 11:48 PM by Shiju Varghese's Blog

After 5 CTP versions and 1 Beta version, Microsoft has finally shipped Release Candidate version of ASP

# Applying Dependency Injection in ASP.NET MVC NerdDinner.com Application

Thursday, March 12, 2009 7:35 AM by Community Blogs

ScottGu , Scott , Phil and Rob have announced a free ASP.NET MVC eBook and an open source ASP.NET MVC

# Richard Dingwall &raquo; Workaround for combining a factory method and LifetimeManager with Unity

Pingback from  Richard Dingwall  &raquo; Workaround for combining a factory method and LifetimeManager with Unity

# re: ASP.NET MVC Tip: Dependency Injection with Unity Application Block

Monday, June 15, 2009 4:49 AM by jbe

How about providing an example with the Dependency Injection Framework MEF which is going to be part of .NET 4.0?

thx

 jbe

# Introduction to Test-Driven Development with ASP.NET MVC

Wednesday, July 22, 2009 12:28 PM by Shiju Varghese's Blog

One of the greatest advantages of ASP.NET MVC is the support of testability, which enables to develop

# Introduction to Test-Driven Development with ASP.NET MVC | rapid-DEV.net

Pingback from  Introduction to Test-Driven Development with ASP.NET MVC | rapid-DEV.net

# Introduction to Test-Driven Development with ASP.NET MVC | I love .NET!

Pingback from  Introduction to Test-Driven Development with ASP.NET MVC | I love .NET!

Leave a Comment

(required) 
(required) 
(optional)
(required)