Saturday, 23 February 2013

ASP.NET MVC 3 Dependency Injection using Unity.MVC3


ASP.NET MVC 3 Dependency Injection
Dependency injection (DI) is a design pattern and it is based on separating component behaviour from dependency resolution without object intervention. In other words we can say it removes the tightly coupled dependency between objects and components in collaboration model where there are contributors and consumers.
To know more about Dependency Injection Pattern, Please follow below links:
http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
Dependency Injection is a particular implementation of Inversion of Control (IoC) principle, which says, An Object should not create other object in which they rely. It means the consumer object receives his dependencies inside constructor properties or arguments.
The advantages of using Dependency Injection pattern and Inversion of Control are:
·         Reduces class coupling
·         Increases code reusing
·         Improves code maintainability
·         Improves application testing

In ASP.Net MVC framework we need Dependency Injection to remove dependency between consumer (say controller) and contributors (service/business layer object).

Now let’s move on Implementation of Dependency Injection in ASP.Net MVC 3. Here we will talk about using Dependency Injection inside an MVC controller. We can also use Dependency Injection inside MVC View and MVC Action Filter.

I assume, you already have the knowledge regarding ASP.Net MVC3.
Before starting first thing we have to do is, IoC container which basically create dependency resolver per HTTP request. And I feel let’s not do that as there are lot many open sources available which provides library to do this like Ninject, Unity and so on.

Here I am going to use Unity.MVC3 and will show you, How you can use Dependency Injection inside controller using Unity.MVC3 IoC library. We will discuss to perform CRUD operation

Introduction of Unity.MVC3:
 A library that allows simple Integration of Microsoft's Unity IoC container with ASP.NET MVC 3. This project includes a bespoke Dependency Resolver that creates a child container per HTTP request and disposes of all registered IDisposable instances at the end of the request.

How to get this library: To include this on project, Right click on your MVC3 app solution in visual studio and click on “Manage NuGet Packages” and search of Unity (refer below pic).

Here you have select Unity.MVC3 (Highlighted on) click to install. Once you installed this you can see below highlighted (in pic) dlls reference in your project:

Next step we will create a service(with interface and implementation)  which is basically responsible to communicate with DB.

And then we create the actual service class which perform all my CRUD operation to create, delete, edit and modify user details to the DB.

Now we will create a controller factory class for Unity which implements IControllerFactory interface, extending CreateController and ReleaseController methods to work with Unity. This factory will create the instances of the controllers that work with Dependency Injection.
Note:
A controller factory is an implementation of the IControllerFactory interface, which is responsible both for locating a controller type and for instantiating an instance of that controller type.
The following implementation of CreateController finds the controller by name inside the Unity container and returns an instance if it was found. Otherwise, it delegates the creation of the controller to an inner factory. One of the advantages of this logic is that controllers can be registered by name.

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

namespace MyMVC3WebApp.Factories
{
    public class UnityControllerFactory: IControllerFactory
    {
        private IUnityContainer unityContainer;
        private IControllerFactory defaultInnerFactory;

        public UnityControllerFactory(IUnityContainer container)
            : this(container, new DefaultControllerFactory())
        {
        }

        protected UnityControllerFactory(IUnityContainer container, IControllerFactory innerFactory)
        {
            unityContainer = container;
            defaultInnerFactory = innerFactory;
        }

        public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            try
            {
                return unityContainer.Resolve<IController>(controllerName);
            }
            catch (Exception ex)
            {
                return defaultInnerFactory.CreateController(requestContext, controllerName);
            }
        }

        public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            return System.Web.SessionState.SessionStateBehavior.Default;
        }

        public void ReleaseController(IController controller)
        {
            unityContainer.Teardown(controller);
        }
    }
}


Now next steps we have to register this Unity Library. While installing Unity.MVC3 you have observed, there is class called Bootstrapper.cs is been added to the solution including above mentioned dlls (shown in below pic, highlighted one).

Now next step we have to register our service Type inside BuilUnityController method present under Bootstrapper class.

Highlighted code in above pic is to register our service.

And the last step we have to do is, call the Initialize method of the Bootstrapper class from the global.asax.cs file. Shown in below pic

Now we have done with the create part and will see how I am using this inside my controller.
      
Now if you see, controller receives the business object through constructor and use this to perform CRUD operation. So here our controller is no more depended on creation object of service class on which it relays.

Please feel free to give your suggestion/feedback.

Thank You for reading this.  

References:

1 comment: