Click here to Skip to main content
15,868,292 members
Articles / Programming Languages / C#
Article

Dependency Injection in MVC Using Unity IoC Container

Rate me:
Please Sign up or sign in to vote.
4.70/5 (22 votes)
15 Jul 2014CPOL3 min read 126K   40   19
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.

C#
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.

C#
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:

Image 1

Image 2

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.

C#
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.

C#
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.

C#
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.

Image 3

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)


Written By
Software Developer DELL International
India India
I am software developer from INDIA. Beside my day to day development work, i like to learn new technologies to 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. Visit to my personal blog here.

http://ctrlcvprogrammer.blogspot.in/

Comments and Discussions

 
SuggestionCustom Controller Factory No Longer Required Pin
X-treem19-Sep-18 1:00
X-treem19-Sep-18 1:00 
QuestionHelp - DI in MVC5 Pin
Member 976627317-Dec-17 22:29
Member 976627317-Dec-17 22:29 
QuestionShort and simple Pin
rahulchow26-Jul-16 4:06
rahulchow26-Jul-16 4:06 
GeneralMy vote of 5 Pin
Luis M. Teijón17-Jul-16 13:41
Luis M. Teijón17-Jul-16 13:41 
GeneralVote of 5 Pin
AbbasHere22-Sep-15 19:19
AbbasHere22-Sep-15 19:19 
Suggestiontry - catch - return Pin
sephirot86089-Sep-15 22:33
sephirot86089-Sep-15 22:33 
GeneralRe: try - catch - return Pin
AbbasHere22-Sep-15 19:14
AbbasHere22-Sep-15 19:14 
QuestionNice Article. Pin
Praveen Raju22-Jun-15 6:07
professionalPraveen Raju22-Jun-15 6:07 
QuestionDependency of a dependency Pin
Akhil Mittal8-May-15 2:07
professionalAkhil Mittal8-May-15 2:07 
AnswerRe: Dependency of a dependency Pin
Nitin Singh India11-Jun-17 12:18
Nitin Singh India11-Jun-17 12:18 
QuestionUnity.Mvc5 Package Pin
itsaranga23-Apr-15 18:31
itsaranga23-Apr-15 18:31 
Thanks for the great article Sourav.

If anyone interested on Unity.Mvc5 package please refer MVC 5 with Unity for Dependency Injection
QuestionGood One Pin
sagar wasule2-Mar-15 3:37
sagar wasule2-Mar-15 3:37 
QuestionGetting error ('MVCIoC.Models.ControllerFactory' did not return a controller) Pin
ajay29jangam30-Jan-15 23:11
ajay29jangam30-Jan-15 23:11 
AnswerRe: Getting error ('MVCIoC.Models.ControllerFactory' did not return a controller) Pin
a.anupkumar087-Aug-15 0:43
a.anupkumar087-Aug-15 0:43 
GeneralMy vote 5 Pin
Hugo Gonzalez Olaya19-Nov-14 12:33
Hugo Gonzalez Olaya19-Nov-14 12:33 
GeneralMy vote of 4 Pin
Akhil Mittal16-Jul-14 5:01
professionalAkhil Mittal16-Jul-14 5:01 
GeneralRe: My vote of 4 Pin
Sourav Kayal16-Jul-14 6:20
Sourav Kayal16-Jul-14 6:20 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun15-Jul-14 19:22
Humayun Kabir Mamun15-Jul-14 19:22 

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

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