Thursday 30 October 2014

Dependency Injection in MVC 4 using Ninject, Unity and StructureMap (IoCs)


Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them.
This software design pattern injects the depended-on element (object or value etc) to the destination automatically by knowing the requirement of the destination.
One of its core principles is the separation of behavior from dependency resolution.
source: Wikipedia.
A dependency is created when your application instantiate a class. Like this:
private MovieRepository _movieRepository = new MovieRepository();
The idea is to use an injector that “injects” this dependency into your application for you.
There are many Dependency Injection Containers also called Inversion of Control Containers (IoC) like:
  • Ninject. Free open source dependency injector for .NET
  • Unity. The Unity Application Block (Unity) is a lightweight extensible dependency injection container with support for constructor, property, and method call injection.
  • StructureMap. StructureMap is a Dependency Injection / Inversion of Control tool for .Net that can be used to improve the architectural qualities of an object oriented system by reducing the mechanical costs of good design techniques. StructureMap is released under the permissive Apache 2 OSS license.  You are free to download, modify, or redistribute StructureMap in any way you see fit  without restriction.
The following examples will use the injectors mentioned previously. It will be based on the Project used for the RepositoryPattern post in this blog.
To use Dependency Injection do the following changes:
1. In MoviesController first we will comment the dependency:
1
2
3
4
5
6
7
8
9
10
public class MoviesController : Controller
{
   // You don't instance a class. Big NO, NO.
   // private MovieRepository _movieRepository = new MovieRepository();
   public ViewResult Index()
   {
      return View(_movieRepository.GetMovies();
   }
}
2. Again in MovieController.cs we change the constructor like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MoviesController : Controller
{
   // You don't instance a class. Big NO, NO.
   // private MovieRepository _movieRepository = new MovieRepository();
   private IMovieRepository _MovieRepository;
   // Constructor must be named exactly as the class
   public MoviesController(IMovieRepository MovieRepository)
   {
      _MovieRepository = MovieRepository
   }
   public ViewResult Index()
   {
      return View(_movieRepository.GetMovies();
   }
}
That concludes the common changes to use injectors. The following examples will explore 3 different dependency injectors.

Ninject Example.

In Visual Studio 2012 go to Tools\Library Package Manager\Manage NuGet Packages look for Ninject IoC Container for .NET, Ninject.MVC3 and Ninject.Web.Common. Add them to your Project.
In NinjectWebCommon.cs add the following code:
1
2
3
4
5
6
using MVCMovieTraining.Models;
private static void RegisterServices(IKernel kernel)
{
   Kernel.Bind<IMovieRepository>().To<MovieRepository>();
}

Unity Example.

If you already did the Ninject example, first delete the 3 references of Ninject and delete the file NinjectWebCommon.cs from App_Start. If not just go to the next step.
In Visual Studio 2012 go to Manage Nuget Packages and install Unity and Unity.MVC3
In Bootstrapper.cs don’t touch the Initialise method, just add the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
using MVCMovieTraining.Models;
namespace MVCMovieTraining
{
   ...
   private static IUnityContainer BuildUnityContainer()
   {
     var container = new UnityContainer();
     container.RegisterType<IMovieRepository, MovieRepository>(new HierarchicalLifetimeManager());
     return container;
   }
}
In Global.asax.cs call the Initialise method, put the line at the end of the Application_Start():
1
2
3
4
5
protected void Application_Start()
{
   ...
   Bootstrapper.Initialise();
}

StructureMap Example.

In Package Manager Console:
PM> Install-Package StructureMap.MVC4
Add a class in the root of the Project “BootStrapper.cs”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using StructureMap;
using StructureMap.Configuration.DSL;
using MVCMovieTraining.Models;
namespace MVCMovieTraining
{
   public class BootStrapper
   {
      public static void ConfigureDependencies()
      {
         ObjectFactory.Initialize(x => x.AddRegistry<ControllerRegistry());
      }
   }
   public class ControllerRegistry : Registry
   {
      public ControllerRegistry()
      {
         For<IMovieRepository>().Use<MovieRepository>();
      }
   }
}
To explore the 3 Dependency Injectors it’s better to start with the Project without Dependency Injection and copy it 3 times then start from there for each Dependency Injector. Otherwise you need to delete the changes made for the previous Dependency Injector.

No comments:

Post a Comment

Angular Tutorial (Update to Angular 7)

As Angular 7 has just been released a few days ago. This tutorial is updated to show you how to create an Angular 7 project and the new fe...