Wednesday, 2 September 2015

Dependency Injection in ASP.NET MVC 5 or MVC 6 with Structure Map

Dependency Injection in ASP.NET MVC 5 or MVC 6 with Structure Map

You people may be wondering why we need dependency injection. So the answer is DI is a design pattern that basically let you to write a loosely coupled testable code or application.
Three types of dependency injection



There are at least three ways an object can receive a reference to an external module



Constructor injection: the dependencies are provided through a class constructor.
Setter injection: the client exposes a setter method that the injector uses to inject the dependency.
Interface injection: the dependency provides an injector method that will inject the dependency into any client passed to it. Clients must implement an interface that exposes a setter method that accepts the dependency.
But Today we will look Constructor injection.



In day to day life of coding or programming our one class generally depend on some other class.
Take a look of my MVC 5 code.







You can see that in index method, it requires to create an instance of "Employee" class to get the full name of a employee. It is very clear that the Index method is tightly coupled with the Employee class.
This is not good when it comes to testing HomeController class. Suppose that you have other methods, with similar types of class dependencies. So, each time when you test the code, you have to pass an actual instance Employee class. This is tedious. You don't have the luxury of passing a fake employee class to easily test your controllers.
So how do we decouple the Employee class from HomeController ? This is our question so



This is where DI comes in handy. You can inject dependencies in several ways. Today i will show you "constructor injection", where you simply inject the dependencies to the constructor of the class. (Ex: in the above example, inject dependencies to the constructor of the HomeController).



So we will look step by step ,How to implement DI using structure map in MVC 5 Application



Step 1 – We have to setup Structure Map



- Lets create a new MVC5 application in Visual Studio 2013/15.
  • Let's use popular "StructreMap" Ioc container to inject dependencies externally. To setup StructreMap, Open a nuget package manager and search for “StructreMap” and install it.
  • You can do the same thing using package manager console powershell.
Step 2 - Create IEmployee interface.



public interface IEmployee
{
string GetFullName();
}



Step 3 - Now Create the actual Employee class/concrete class. This class implements IEmployee interface.



public class Employee: IEmployee
{
public string GetFullName()
{
return "Ravi Kumar Singh";
}
}



Step 4 - Go to the HomeController. Since we use constructor injection, let's create a constructor for the HomeController. It will look similar to this.



public class HomeController : Controller
{
private readonly IEmployee _employee;



// constructor
public HomeController( IEmployee employee)
{
this._employee = employee;
}
//action method
public ActionResult Index()
{
return Content(this.employee.GetFullName());
}
}



Notice that, we are passing the IEmployee interface as the parameter for the constructor. Then we saved the passed parameter into a instant variable of type IEmployee. So what is the benefit of doing this?



Now you can pass any class that implements IEmployee interface to our HomeController. We can create a dummy class which implements IEmployee with dummy data and simply test our HomeController quite easily!



To do this, we need a way to Map our IEmployee interface either with Actual Class or Dummy Class. This is facilitated by our Ioc container "StrutureMap".



Step 5 - Goto ~/DependencyResolution -> IoC.cs file. This file is automatically created once you installed StructureMap. Change it as follows.



public static class IoC {
public static IContainer Initialize() {
ObjectFactory.Initialize(x =>
{
x.For<IEmployee>().Use<Employee>();
});
return ObjectFactory.Container;
}
}



x.For<IEmployee>().Use<FakeEmployee >();
You can easily replace the Actual Employee class with a Dummy Class. That's it.







Done ;)

1 comment: