This article assumes a basic understanding of the de-coupled architecture and Inversion of Control (IoC) principal. If you are very new in both concepts I recommend you understand both first. We all know that the de-coupled architecture is one of the major goals of a good design pattern in applications and Inversion of Control is the way to do that. As the name Inversion of control suggests, we will redirect the control follow in a reverse order to implement de-coupled architecture.
There are the following two implementations of Inversion of Control:
- Dependency Injection
- Service locator.
In this example we will implement Dependency Injection using Unity within a MVC5 application. So, to follow this article I suggest you create an Empty MVC 5 application and install the following packages from the NuGet Package Manager.
Please note that Unity is a product from Microsoft and it will help us to create a repository of dependency classes that will be pluggable in mode. In other words, the main advantage of Unity is that if needed we can just plug it in with another application.
Use the following procedure to install the following packages:
Once installed successfully you will find that the following assembly has been added to the application.
Step 1: Create Unity container
Fine, we will now add a Bootstrapper class to the application. Take one .cs file and modify it accordingly.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using DITest.Repository;
- using Microsoft.Practices.Unity;
- using Microsoft.Practices.Unity.Mvc;
-
- namespace DITest
- {
- 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<ICompanyRepository, CompanyRepository>();
-
-
- RegisterTypes(container);
- return container;
- }
- public static void RegisterTypes(IUnityContainer container)
- {
-
- }
- }
- }
This is the Bootstrapper class to be implemented to create a container of dependency objects. Please note that we have added the following lines:
- container.RegisterType<ICompanyRepository, CompanyRepository>();
To the BuildUnityContainer() function. The line is to register the Interface and it's implementation in the container, we will create both shortly.
Step 2 : Register container class
We will now register the container class in the global.aspx page. Here is the screen of my global.aspx page.
This single highlighted line will register the Unity container in the application.
Step 3 : Create class /Model
We will now create the model/class. In this example I have decided to implement one “company” class, that will hold a few eices of company information. The definition is as in the following.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
-
- namespace DITest.Repository
- {
- public class Company
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public string Category { get; set; }
- }
- }
It's simple, just three properties. In reality it could contain many properties or if you are using Entity Framework then by default, the model will be created for you.
I recommend you create a folder called “Repository” in the solution and keep the model in that place, because in the future we will add two more classes to deal with the mode.
Step 4 : Create Interface
Create one IProductRepository.cs file in the “Repository” folder and modify the code accordingly as in the following:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
-
- namespace DITest.Repository
- {
- public interface ICompanyRepository
- {
- IEnumerable<Company> GetAll();
- Company Get(int id);
- Company Add(Company item);
- bool Update(Company item);
- bool Delete(int id);
- }
- }
We are seeing that the interface is targeting CRUD operations over the collection. When we call the GetAll() function it will return a collection of “Company” information. It will help us to implement the de-coupled architecture in the application. Very shortly we will implement it in the Repository class.
Step 5 : Implement interface in CompanyRepository.cs file
We will now implement the interface in the actual class. So, we will create a CompanyRepository.cs file within “Repository” older and modify it accordingly. The implementation is very easy to understand, since we are just doing CRUD operations on the Company list. All functions and it's operations are self-defined.
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
-
- namespace DITest.Repository
- {
- public class CompanyRepository : ICompanyRepository
- {
- private List<Company> products = new List<Company>();
- private int _nextId = 1;
-
- public CompanyRepository()
- {
-
- Add(new Company { Name = "TIMKEN Eng", Category = "Engenering"});
- Add(new Company { Name = "Wipro", Category = "software"});
- Add(new Company { Name = "HSBC", Category = "Bank"});
- }
-
- public IEnumerable<Company> GetAll()
- {
-
- return products;
- }
- public Company Get(int id)
- {
-
- return products.Find(p => p.Id == id);
- }
- public Company Add(Company item)
- {
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
-
-
- item.Id = _nextId++;
- products.Add(item);
- return item;
- }
- public bool Update(Company item)
- {
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
-
-
- int index = products.FindIndex(p => p.Id == item.Id);
- if (index == -1)
- {
- return false;
- }
- products.RemoveAt(index);
- products.Add(item);
- return true;
- }
- public bool Delete(int id)
- {
-
- products.RemoveAll(p => p.Id == id);
- return true;
- }
- }
- }
Step 6 : Add controller class to the application
We will now add one controller class and from there we will consume the data of the Company model. Here is the controller class.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using DITest.Repository;
- using Newtonsoft.Json;
-
- namespace DITest.Controllers
- {
- public class CompanyController : Controller
- {
- readonly ICompanyRepository repo;
- public CompanyController(ICompanyRepository tempProduct)
- {
- this.repo = tempProduct;
- }
- public string Index()
- {
- var data = repo.GetAll();
- return JsonConvert.SerializeObject(data);
- }
- }
- }
If you observe the controller class, you will find that we are not creating an object of a concrete class within the controller, we are using an ICompanyRepository interface.
From the Index() action I am interested in returning a JSON result , since I am not using any view, so I can consume the result in Fiddler.
Conclusion
We have now seen how to implement IoC using the Unity framework. I hope this will help to implement the de-coupled architecture in your application. The great advantage of Unity is, it's a container and once you register our object within the container, you can use it anywhere.