.netASP.Net MVC

Dependency Injection in ASP.net MVC

In this article, we will learn:

  • What is Dependency Injection?
  • Advantages of Dependency Injection
  • Dependency Inversion Principles
  • Inversion of Control Principles
  • Applying Dependency Injection in ASP.net MVC

What is Dependency Injection?

  • Dependency Injection (DI) is a design pattern that takes away the responsibility of creating dependencies from a class thus resulting in a loosely coupled system
  • The core features of the DI container have been abstracted out to the <span style="font-family: Courier New;">IServiceProvider</span> interface and are available throughout the stack. Because the <span style="font-family: Courier New;">IServiceProvider</span> is the same across all components of the ASP.NET framework a single dependency can be resolved from any part of the application. 
  • The DI container supports just 4 modes of operation:
    • Instance – a specific instance is given all the time. You are responsible for its initial creation.
    • Transient – a new instance is created every time.
    • Singleton – a single instance is created and it acts like a singleton.
    • Scoped – a single instance is created inside the current scope. It is equivalent to Singleton in the current scope.

Advantages of Dependency Injection:

  • Reduces class coupling
  • Increases code reusing
  • Improves code maintainability
  • Improves application testing

Example:

Let’s see an example to understand Dependency Injection better.

 The Employee class declares a variable of type DatabaseHelper.

The DatabaseHelper class is supposed to be doing some database operations such as SELECT and UPDATE.

The constructor of the Employee class instantiates the DatabaseHelper class and the instance is stored in the helper variable. In this case the Employee class is dependent on the DatabaseHelper class for its functioning. Thus DatabaseHelper is a dependency of the Employee class.

The problem with the above design is that the Emplyee class and DatabaseHelper class are tightly coupled.

If you ever need to substitute DatabaseHelper with some other class (say XMLHelper) then you will have to change the code of the Employee class since it directly instantiates the DatabaseHelper. To help avoid this, tight coupling Dependency Inversion Principle (DIP) is used.

The DIP states that – High-level modules should not depend on low-level modules. Both should depend on abstractions. That means Employee should not depend on a concrete implementation (DatabaseHelper) but rather should depend on an abstraction. At code level this means the Employee class won’t have a variable of DatabaseHelper type, instead it will have a variable of some interface (or abstract class) type.

This is shown below:

 Now, the Employee class uses a variable of type IStorageHelper interface everywhere. IStorageHelper is supposed to be an interface that is implemented by the DatabaseHelper class and all such classes. so most of the code of the Employee class is now using an abstraction in the form of IStorageHelper.

Although the above code is better than the original implementation, it still has a problem. The helper variable is still instantiated inside the Employee class. This problem arises because the Employee class is responsible for creating its dependency (DatabaseHelper).

The Inversion of Control principle (IoC) comes in to picture in such cases. IoC states that the control of creating the decencies should be with the external system rather than the class itself. In the above example this means that the Employee class shouldn’t create an instance of DatabaseHelper, rather it should be received from the external system.

Dependency Injection is a way to implement IoC such that the dependencies are “injected” into a class from some external source. The injected dependencies can either be received as constructor parameters of a class or can be assigned to properties of that class designed for that purpose. The former approach is commonly used in ASP.NET MVC. 

So, the above code now becomes:

so now, the helper instance is now coming from the external world and is being injected into the Employee class through its constructor.

Applying Dependency Injection in ASP.net MVC:

So now we know what is Dependency Injection, Let’s see how to apply Dependency Injection in ASP.net MVC.

Below is the Controller:

 The HomeController class declares a variable of IEmployeeRepository. The IEmployeeRepository is an interface designed to implement the Repository Pattern and is shown below:

We will discuss on Repository Pattern in next article.

In the above code some implementation of IEmployeeRepository is injected inside the HomeController through its constructor. As you can see the Index() action method calls the SelectAll() method on the repository to retrieve all the Employees as a List of EmployeeViewModel objects. The EmployeeViewModel is a simple class that acts as a view model and is shown below:

 Although the above code seems to apply DI as expected there is a problem. The problem is that while instantiating the HomeController for processing the incoming requests, ASP.NET MVC framework uses the parameter less constructor of the HomeController. Since our HomeController no longer has one, the above code throws an exception at runtime. ASP.NET MVC allows you to explicitly specify how controllers should be instantiated. This can be done by creating your own Controller Factory.

A controller factory is a class that usually inherits from DefaultControllerFactory class and is responsible for creating controller instances. Once created you need to register your custom controller factory with the ASP.NET MVC framework so that it can use your controller factory instead of the default one.

Let’s create the custom controller factory first. Have a look at the following code:

The MyControllerFactory class inherits from the DefaultControllerFactory class provided by the ASP.NET MVC framework. The constructor of MyControllerFactory accepts an instance of IEmployeeRepository. This way the MyControllerFactory doesn’t depend on any concrete implementation of IEmployeeRepository. The code then overrides the CreateController() method of the base class. A Dictionary objects maintains a list of controllers in the application. Notice that HomeController is being instantiated in the constructor and is stored with a key of Home. The CreateController() simply returns this instance of HomeController from the Dictionary.

Now that the Employee controller factory is ready, you need to register it with the ASP.NET MVC framework. To help you with this registration we create a helper class – ControllerFactoryHelper – as shown below:

 The ControllerFactoryHelper class has just one static method, GetControllerFactory(). The job of GetControllerFactory() is to instantiate MyControllerFactory and prepare for the registration. This is the place where the concrete implementation of IEmployeeRepository are required. This is so because unless these details are known you can’t instantiate MyControllerFactory (since the constructor of MyControllerFactory needs an object implementing IEmployeeRepository). The above code assumes that these details are stored in the <appSettings> section of the web.config file as shown below:

  1. <appSettings>
  2.   …
  3.   <add key=“repository” value=“DIDemo.Repositories.EmployeeRepository”/>
  4. </appSettings>

The GetControllerFactory() reads the repository key and creates an instance of DIDemo.Repositories.EmployeeRepository using Reflection.

It then instantiates MyControllerFactory by passing this object. The factory object is then returned to the caller.

Now comes the final step. To register the Employee controller factory you need to add the following code in Global.asax:

The Application_Start event handler uses the ControllerBuilder instance and calls its SetControllerFactory() method.
The factory object returned by the GetControllerFactory() static method is passed as a parameter to the SetControllerFactory() method.

When you will run the IndexView, you will see list of all Employees.

© 2015, www.techkatak.com. All rights reserved.

One thought on “Dependency Injection in ASP.net MVC

Comments are closed.