ASP.NET MVC - Getting started with Unity IoC Container

In one of my recent discussions with a client, we talked about how to decouple model layers with the controller layer in an ASP.NET MVC application. Generally a decoupled design helps maintainability and Unit Testability of an application.

There are various frameworks already available for implementing Dependency Injection, like Ninject. You can get more information about it in the articles Dependency Injection in ASP.NET MVC - An Introduction and Dependency Injection Using Ninject In ASP.NET MVC. In this small article, we will explore the library Unity.MVC 3. This library allows an integration of Microsoft's Unity IoC container with ASP.NET MVC 3.You can find additional details about this library over here.

Getting Started with Unity

Step 1: Open Visual Studio 2012 and create a new MVC application. Right click on the project and add the NuGet package for Unity.Mvc3 as shown below:

unity-mvc-package

This will add Unity.Mvc3.dll in the project along with the Bootstrapper.cs class file at project level, as shown below:

using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Unity.Mvc3;
using MVC4_Using_Unity.ServicesRepository;

namespace MVC4_Using_Unity
{
public static class Bootstrapper
{
  public static void Initialise()
  {
   var container = BuildUnityContainer();
   DependencyResolver.SetResolver(new UnityDependencyResolver(container));
  }

  private static IUnityContainer BuildUnityContainer()
  {
   var container = new UnityContainer();
   // register all your components with the container here
   // it is NOT necessary to register your controllers
   // e.g. container.RegisterType<ITestService, TestService>();           
   return container;
  }
}
}

The above class provides registration points for the dependency resolvers using ‘DependencyResolver’ class. The method ‘BuildUnityContainer’ is used to register dependencies of the component which MVC application component (e.g. Controllers) wants to use it.

Step 2: To add the model layer, ADO.NET EF is used here for the EmployeeInfo table in Company database of SQL Server. The Script for the Table is as shown below:

USE [Company]
GO

/****** Object:  Table [dbo].[EmployeeInfo]    Script Date: 1/17/2013 12:55:25 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[EmployeeInfo](
    [EmpNo] [int] IDENTITY(1,1) NOT NULL,
    [EmpName] [varchar](50) NOT NULL,
    [Salary] [decimal](18, 0) NOT NULL,
    [DeptName] [varchar](50) NOT NULL,
    [Designation] [varchar](50) NOT NULL,
CONSTRAINT [PK_EmployeeInfo] PRIMARY KEY CLUSTERED
(
    [EmpNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO

Use the Wizard for ADO.NET EF. After completing the wizard, the Entity will be displayed as shown below:

entity

Step 3: Add a new Folder in the project of the name ‘ServicesRepository’. Add the following interface and a class in this folder:

public interface IEmployeeInfoService
{
IEnumerable<EmployeeInfo> GetEmployees();
void AddEmployee(EmployeeInfo Emp);
}

public class EmployeeInfoService :IEmployeeInfoService
{
CompanyEntities objContext;
public EmployeeInfoService()
{
  objContext = new CompanyEntities();
}

public IEnumerable<EmployeeInfo> GetEmployees()
{
  return objContext.EmployeeInfoes.ToList();
}

public void AddEmployee(EmployeeInfo Emp)
{
  objContext.AddToEmployeeInfoes(Emp);
  objContext.SaveChanges();
}
}

The above is the new layer added in the project. The class EmployeeInfoService implements IEmployeeInfoService interface. The methods from this class makes a call to ADO.NET EF. The above layer will be used to decouple the model layer from the controller layer.

Step 4: Decoupling the implementation from the interface, add the following line in the BuildUnityContainer method of the Bootstrapper class:

container.RegisterType<IEmployeeInfoService, EmployeeInfoService>();

The above line registers EmployeeInfoService along with its interface in the Unity container.

Step 5: Register the Bootstrapper class with the Global.asax in Application_Start method so that it can initialize all dependencies. This can be done by calling Initialize() method of the Bootstrapper class in the Application_Start method as shown below:

Bootstrapper.Initialize();

Step 6: Add the EmployeeInfoController class in the Controllers folder and inject the dependency for the IEmployeeInfoService interface using a constructor as shown below:

public class EmployeeInfoController : Controller
{
private readonly IEmployeeInfoService EmployeeInfoService;
/// <summary>
/// Injecting dependency using constructor
/// </summary>
/// <param name="empserv"></param>
public EmployeeInfoController(IEmployeeInfoService empserv)
{
  EmployeeInfoService = empserv;
}
//
// GET: /EmployeeInfo/
public ActionResult Index()
{
  var Employees = EmployeeInfoService.GetEmployees();
  return View(Employees);
}
}


Step 7: One important thing here is that since we are using a ready framework Unity for dependency injection, we must debug the application, so apply breakpoints on:
  • Global.asax->Application_Start method.
  • BootStrapper.cs ->BuildUnityContainer method
  • EmployeeInfoController.cs->Constructor and Index action method.
Step 8: Run the application, the debugger reaches Application_Start, use F11 to enter into BootStrapper class and its BuildUnityContainer method. Here if you see the registration of the IEmployeeInfoService, you will find instances of the EmployeeInfoService created which is available to the constructor of the EmployeeInfoController constructor.

Step 9: Finally when the Index action method is called, the result will display all Employees.

Conclusion

With a few steps, we were able to introduce an IoC container to help us inject Dependencies like the Repository Interface into the Controller (UI Layer). Thus this implementation is now decoupled from the interfaces and can be easily swapped if required. The Unity.Mvc3 wrappers make it really easy to get started with DI using Unity.

Source code for the sample can be downloaded from our GitHub repository here




About The Author

Mahesh Sabnis is a Microsoft MVP having over 18 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). He also blogs regularly at DotNetCurry.com. Follow him on twitter @maheshdotnet

2 comments:

Anonymous said...

Getting started with Unity IoC Container with simplest lab, thank you sir...

Anonymous said...

What is CompanyEntities ?