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

Tagged as

Dependency Injection in MVC Using Unity IoC Container

, 15 Jul 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
In this article we will learn the implementation of dependency injection using the Unity container

Dependency injection in MVC using Unity IoC container

If you have experience in software design and follow (or at least try to follow) perfect design pattern and principals, then dependency injection, de-couple architecture, and Inversion of Control (IoC) are very common terms for you. You might have hands on experience with the implementation of dependency injection in various programming languages (with or without any IoC container). In this article, we will discuss the relationship between dependency injection and IoC containers and then we will see how IoC containers and dependency injection fit side by side.

What is IoC container ?

The DI container or IoC container is a software framework used to create dependencies and inject them automatically when required. Truth to be told, some dependency containers work like magic when it needs to resolve dependency. There are many such frameworks available in the market to simplify our work and here are a few which work in the .NET environment. So the choice is completely yours, they each have their own benchmarks and performance so choose wisely depending on your project and requirements. As this is article is not dedicated to the IoC container, I will not stretch the discussion on it too far. In this article we will use Unity as an IoC container to resolve dependency.

Let’s Implement Controllers with Dependency

As the heading indicates, we will implement MVC architecture to help understand the concept and then we will create two controllers with some of the dependency in each of them and see how we can solve the dependency using an IoC container. Here is the code of the first controller. The implementation is very simple, we have created an Ilogger interface and there are two implementations of ILogger: one is ActualLogger which is not yet completed, and as substitute we have implemented another class, FakeLoggerm which we will use in code development.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCIoC.Controllers
{
    public interface ILogger
    {
        Boolean Log();
    }
    public class ActualLogger : ILogger
    {
        public Boolean Log()
        {
            throw new NotImplementedException();
        }
    }

    public class FakeLogger : ILogger
    {
        public Boolean Log()
        {
            return true;
        }
    }

    public class HomeController : Controller
    {
        public readonly ILogger logger = null;
        public HomeController(ILogger tmpLogger)
        {
            logger = tmpLogger;
        }
        public ActionResult Index()
        {
            //perform logging information
            logger.Log();
            return View();
        }
    }
}

So the idea is that, if our actual implementation is in the development phase, we can still continue our controller development using some kind of substitution and in time, we can change it without affecting the existing code. So we are seeing that the Home controller has one parameterized constructor. As a parameter it will take the actual implementation of a dependent object. Let’s create another controller; the implementation will be exactly the same as the above one. I just wanted to show how to solve dependency in multiple controllers.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCIoC.Controllers
{
    public interface IService
    {
        Boolean Call();
    }
    public class RealService : IService
    {
        //Real service is not developed yet.
        public bool Call()
        {
            throw new NotImplementedException();
        }
    }
    public class FakeService : IService
    {
        public bool Call()
        {
            return true;
        }
    }
    public class ValueController : Controller
    {
        public readonly IService service = null;

        public ValueController(IService tmpService)
        {
            service = tmpService;
        }

        public ActionResult Index()
        {
            //User service to implement business logic
            service.Call();
            return View();
        }
	}
}

OK, we have setup everything. Now we will give a reference of Unity Framework. If you are using Visual Studio then you can use NuGet Package Manager to give reference. I have given the following references as an example:

Now we will implement our own controller factory class from the DefaultControllerFactory class. There are other options you can implement as well. For example, IController performs the same operation. Here we have defined ControllerFactory and derived from the DefaultControllerFactory class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Practices.Unity;
using MVCIoC.Controllers;

namespace MVCIoC.Models
{
    public class ControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(RequestContext requestContext, 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 MvcUnityContainer.Container.Resolve(controllerType) as IController;
            }
            catch
            {
                return null;
            }

        }
    }

    public static class MvcUnityContainer
    {
        public static UnityContainer Container { get; set; }
    }

}

You can see that we are resolving the dependency within the try block and it will create a controller object by resolving dependency. In the case of the Unity container, we will create a Bootstrapper class to set all the dependencies in a single file. Have a look at the code below. Though it’s not mandatory to implement Bootstrapper it’s always a good practice to implement it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Mvc;
using MVCIoC.Controllers;

namespace MVCIoC.Models
{
    public class Bootstrapper
    {
        public static IUnityContainer Initialise()
        {
            var container = BuildUnityContainer();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            return container;
        }
        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();
            container.RegisterType<IService, FakeService>();
            container.RegisterType<ILogger, FakeLogger>();
            MvcUnityContainer.Container = container;
            return container;
        }
    }  
}

Please notice that we have mapped FakeService and FakeLogger with its interface because our aim is to use the implementation of FakeService and FakeLogger. Once the development of the original implementation is done you can just change in this place, there is no need to touch your controller code. Now the final implementation is registration. We have to register our IoC container in the MVC channel. Just modify your Application_Start() code as shown below.

		protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //Initialize IoC container/Unity
            Bootstrapper.Initialise();
            //Register our custom controller factory
            ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));
        }

Now, it’s time to run the application. Once we call the home controller you will see that the object of FakeLogger has injected to the constructor of the Home controller.

Border Line

There are many IoC containers available on the market. You can choose any one of them, and all IoC containers work more or less in the same way.

License

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

Share

About the Author

Sourav Kayal
Software Developer TIMKEN India research Institute
India India
I am software developer from INDIA, working in manufacturing domain. Beside my day to day development work, i like to learn new technology and update myself. I am passionate blogger and author in various technical community including dotnetfunda.com , c-sharpcorner.com and codeproject. My area of interest is modern web technology in Microsoft stack.
Follow on   LinkedIn

Comments and Discussions

 
GeneralMy vote 5 PinmemberHugo Gonzalez Olaya19-Nov-14 13:33 
GeneralMy vote of 4 PinmvpAkhil Mittal16-Jul-14 6:01 
GeneralRe: My vote of 4 PinmemberSourav Kayal16-Jul-14 7:20 
GeneralMy vote of 5 PinmemberHumayun Kabir Mamun15-Jul-14 20:22 

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
Web01 | 2.8.141216.1 | Last Updated 15 Jul 2014
Article Copyright 2014 by Sourav Kayal
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid