CodeDigest.Com Logo
Featured:

What is Dependency Injection? How to use this Pattern in Asp.Net MVC?

Dependency Injection is a well-known design pattern to create loosely coupled components. In general, a good software design should have high cohesion and low coupling. This means that a software component, for instance, a class or a module or a component should maintain a high degree of holding the related pieces together to make high cohesion and at the same time it should have very low degree of holding dependent pieces together to achieve less coupling. To enable low degree of coupling, the class (or module or a component) should not directly use the concrete implementation of the dependent object and instead work on the abstract object (an interface).

The Dependency Injection commonly called DI pattern helps to inject the concrete implementation of dependent object and finally achieve a low degree of coupling. So, this frees the class from instantiating dependent object and in other words, it does not have any knowledge of the dependent service implementation. It just uses the service that are injected into it at runtime.

For example, an Employee object should have all directly related properties (name, email, dob, etc.) and methods in the class and the other dependencies services like Address Validation or Tax Id Validations methods should not be part of the object.  A more simple and common requirement is, the Controller class should not directly use the concrete Data Access object instead use a reference of abstract object  to make it loosely coupled with data access code. During runtime, this reference is substituted by a concrete implementation object. This also enable us to easily replace the dependent data access object with a different implementation with less effort.

Dependency Injection Pattern in Asp.Net MVC

Let’s build a simple application to understand DI pattern. First, let’s build a controller and action methods which access a concrete data access class without using Dependency Injection.

 

public class EmployeeController : Controller
{      
    // GET: Employee
    public ActionResult Index()
    {
        DBModel db = new DBModel();
        IList<Employee> empList = db.Employees.ToList();
        return View(empList);
    }
    public ActionResult Get(int Id)
    {
        Employee emp = db.Employees.Where(e => e.EmployeeId == Id).FirstOrDefault();
        return View(emp);
    }
}
 

The above controller class uses the Code First context class directly which makes the controller a highly dependent on the EF context class DbModel. This means if you want to replace the EF Code First with a different implementation then you need to make a lot of code changes. Since, the controller is heavily tied up with DBModel class the unit testing involves using DBModel object as well i.e. when testing the action method you are not actually testing only the unit of code in controller action instead your test includes EF Code First data access code too. It is also very difficult to use a mock object in the place of DBModel since the action method is dependent on concrete DBModel object. This breaks our design assumption to build a loosely coupled application.

To solve this issue, we need to plug out the concrete dependent object (DBModel in our case) from controller and make the controller to use an abstract dependent object instead of concrete object. We generally use Repository pattern to assist in this scenario. Repository pattern allows you to segregate the data access code from controller and easily replace it with a different implementation. Repository pattern exposes all the operations in an interface which can be used in controller. We can have multiple implementation of this interface which can be swapped using Dependency Injection.

In our case, we will have a IEmployeeRepository like below,

 

public interface IEmployeeRepository
{
    Employee Get(int Id);
    List<Employee> GetAll();
}
 

Now, we can have multiple implementation of this repository each with different data access technology. Let’s implement an EmployeeRepository that uses EF Code First with the above interface,

 

public class EmployeeRepository : IEmployeeRepository
{
    DBModel db = new DBModel();
    public Employee Get(int Id)
    {
        return db.Employees.Where(e => e.EmployeeId == Id).FirstOrDefault();
    }
    public List<Employee> GetAll()
    {
        return db.Employees.ToList();
    }
}
 

You can add another repository like EmployeeADORepository that uses plain ADO.Net code for data access if required.

Next, let’s change EmployeeController class to use the repository instead of DBModel class directly and understand how it makes the controller loosely coupled with repository class.

 

public class EmployeeController : Controller
{
    IEmployeeRepository repositoryEmployee;

    public EmployeeController()
    {
        repositoryEmployee = new EmployeeRepository();
    }

    // GET: Employee
    public ActionResult Index()
    {
        IList<Employee> empList = repositoryEmployee.GetAll();
        return View(empList);
    }
    public ActionResult Get(int Id)
    {
        Employee emp = repositoryEmployee.Get(Id);
        return View(emp);
    }
}
 

If you see the above controller, we are actually instantiating the repository inside the controller constructor. The above method where we are manually instantiating the dependency in constructor is commonly called as Manual Dependency Injection. Doing like this, if we want change the data access with ADO.Net repository then it is as easy as changing one line of code in constructor.

 

public EmployeeController()
{
    repositoryEmployee = new EmployeeADORepository();
}
 

The other common way of injecting the dependencies is through constructor injection using some freely available IOC (Inversion of Control) Containers or Dependency Injection Containers like Autofac, Ninject, StructureMap, Unity, etc.

 

public EmployeeController(IEmployeeRepository _repoEmployee)
{
    repositoryEmployee = _repoEmployee;
}
 

MVC framework allows to add CustomControllerFactory implementation to register these IOC containers which will actually take of care of object instantiation and injecting it into the controller constructor.

The Dependency Injection can also be done at method parameter level and using public property setter apart from constructor injection. Asp.Net Core MVC framework has a inbuilt support for DI Containers for injecting depedendent services accross application.

Happy Learning!!