Implement Dependency Injection using Unity in ASP.NET MVC Controller

Download Source Code

Introduction

In this article we will learn how to implement Dependency Injection using Unity in MVC Controller.

What is Dependency Injection?

Dependency Injection is a Design Pattern and is an implementation of Inversion of Control (IOC). This design pattern says that objects do not create other objects on which they rely to do their work instead they get the object from outside source. That means if Class A depends on Class B then Class A should not create the object of Class B rather it should get the object of Class from the calling method. That calling method should not directly pass the object of Class B to Class A instead they should use Interfaces to do that. See the code example

Public Class A
{
   B _b;
   public A(B b)
   {
      _b = b;
   }
   public void SomeMethod()
   {
     _b.DosomeWork();
   }
}

If you see in the above we are passing the object of Class B in the constructor of Class A that means Class A and Class B are tightly coupled. If in future Class A wants to use the DoSomeWork method of Class C then whole implementation will be changed.
This problem can be solved by using Dependency Injection. We will use Interface to remove tight coupling between Class A and Class B. See the code below

public Interface Iface 
{
  void DoSomeWork();
}

public Class B : Iface
{
  public void DoSomeWork()
  {
   ///TO DO List
  }
}
Public Class A
{
   Iface _b;
   public A(Iface b)
   {
      _b = b;
   }
   public void SomeMethod()
   {
     _b.DosomeWork();
   }
}

So instead of passing the object of Class B we are now passing the Interface Iface. Class B implements the Interface Iface.

Implementation of Dependency Injection in MVC Controller:

In simple OOPS term Controller is a class which is derived from the Base class Controller. When you add a Controller in your MVC application you will the Class Name like this:

 public class HomeController : Controller

That simply means that HomeController class is derived from Controller class. So far we know What Dependency Injection is and basically HomeController is a class.

Our requirement

Now we will explain DI in MVC with a live scenario. We have our MVC project which has multiple Controllers and like our all other Applications we will have a logging functionality in our Application.
Now the requirement in the Application is that we can have two types of Logging. One logging where we write in the txt file and other logging where we write in the Database Table and based on the Business scenarios we should be able to switch logging mechanism very easily. I hope you are clear with the requirement. If not please read the requirement again. Remember we will implement Dependency Injection Design Pattern now. We will use Unity provided by Microsoft to implement Dependency Injection. Its implementation is pretty straight forward. Complex part is understanding Dependency Injection and using it in MVC controller. Below are the steps to implement DI

  1. Now we will create our two loggers. One will log in txt file and other will log in the Database. I will just provide the skeleton for these classes. You are free to write the code for these classes as per your requirement. I will explain txt logging by using basic principles of File Handling. In actual applications we should use better logging techniques. Log4net is one open source library which is very good in doing File as well as Database logging. You are free to explore Log4net and other libraries. Here we are concentrating on Dependency Injection by using the example of Logging.
  2. Now we will create our Interface. Add a new folder at Project level in Visual Studio and name it Logger.
    Add a new Interface in this Folder and name it Ilogger. The Ilogger interface should look like this

      public interface ILogger
        {
            void Log(string message);
        }
    

    Now this Log method will be implemented by our Logger classes which we will create in next step

  3. At project level Add a new Folder and name it Logger. Add two classes in this folder and name them FileLogger and DBLogger.
    In this tutorial we will implement Log method of Ilogger interface in FileLogger class. Similarly you can implement this method in DBLogger class.
    Out FileLogger class should look like this:

     public class FileLogger : ILogger
        {
            #region ILogger Members
            public void Log(string message)
            {           
                string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs") + @"\logs.txt";
                if (string.IsNullOrEmpty(message))
                    message = "No log message";
                File.AppendAllText(path, message);
            }
            #endregion
        }
    

    DBLogger should look like this (No implementation in this tutorial):

     public class DBLogger : ILogger
        {
            #region ILogger Members
            public void Log(string message)
            {
                throw new NotImplementedException();
            }
            #endregion
        }
    
  4. In above step our FileLogger has implemented the Log method and is writing the log messages in logs.txt. The path i have mentioned for the log.txt is the Logs folder in the Application. At project level Add a new folder and name it Logs. File.AppendAllText method will create the file if it doesn’t exist and write the message in it. In real applications this Log method should have better technique to write in the log file.
  5. So now our Interface is ready and our Logging classes are also ready. Now we need to use either of the Class in our Application for Logging and remember we should be able to switch the logging mechanism with ease. In next step we will create our Controller.
  6. Right click on the Controller folder and Add a new Controller and name it HomeController. Now at class level create a new private variable of the Ilogger interface

    ILogger _ilog;
    

    Now create the Contructor of the HomeController class and pass ILogger parameter to this constructor and assign this value to the _ilog variable. Our constructor will look like this

     public HomeController(ILogger ilogger)
            {
                _ilog = ilogger;
            }
    

    Run the application now and you will see the below error in your application:

    If you see this error it says that No Parameterless Constructor defined. To understand this error create a new paramterless constructor of HomeController. This should look like this

     public HomeController()
            {
            }
    

    Run the Application and put a break point in this Constructor. You will see that view has not been rendered and code execution will stop at this break point. So HomeController constructor gets executed by default as the first thing. But we want to call our parameterised Constructor. In next steps we will see how to call this Constructor and pass the Ilogger value to it.

  7. Open Nuget Packet Manager and Install Unity in your project. There are multiple versions of Unity and for this example i have installed Unity.Mvc3

    You should install Unity as per the version of your MVC.

  8. Till now we have our paramterised HomeController constructor and have Unity installed in our project. Now we need to pass the Ilogger value to the constructor. For this Add a new Class in the App_Start folder in your project. Name this class DIConfig and create a new method RegisterComponent in this class. This class should be static so the method will also be static. In next steps you will get an idea why we created this class as Static. Now in this RegisterComponent we will use Unity to create the object of FileLogger pass it to the HomeController constructor.
  9. Our DIConfig class will look like this

     public static class DIConfig
        {
            public static void RegisterComponent()
            {
                var unityContainer = new UnityContainer();
                unityContainer.RegisterType<ILogger,FileLogger>();
                DependencyResolver.SetResolver(new UnityDependencyResolver(unityContainer));
            }
        }
    

    Here we have mapped Ilogger interface with FileLogger class. So whenever object of Ilogger interface is used it will refer to FileLogger class. Thanks to Unity. In next step we will call this method in the Application start so that this mapping is registered.

  10. Open Global.asax file and in the Application_start method add below line of code

    DIConfig.RegisterComponent();
    

    Now run the application and you will see that our paramterised constructor of HomeController has been called and Ilogger refers to the instance of FileLogger class. Similary by just changing in the RegisterComponent method of DIConfig class we can map the Ilogger interface with DBLogger.

  11. If you recall the definition of Dependency Injection HomeController class is not creating the object of either FileLogger or DBlogger class rather it is depending on the outside world to pass on the object. This is loosely coupled Architecture where we are using Interface to pass the instance of the required class. I hope you enjoyed reading this article. Any suggestions to improve it or any issues please comment.

Leave a Reply

Your email address will not be published. Required fields are marked *