Dependency Injection Using Ninject In ASP.NET MVC

Posted by: Sumit Maitra , on 8/23/2012, in Category ASP.NET MVC
Views: 120280
Abstract: This article walks you through the basics of Dependency Injection and how to use an Inversion of Control (IoC) container – Ninject in a sample ASP.NET MVC Web application

Over the last several years, as software development processes have matured a number of best practice postulates have been realized and then formalized. One of the famous ones goes by the acronym SOLID proposed by Robert C. Martin (fondly known as Uncle Bob Martin). SOLID stands for Single responsibility, Open closed principle, Liskov substitution principle, Interface segregation principle and Dependency Inversion.

Dependency Injection is a way to achieve Dependency Inversion and Inversion of Control (IoC) containers are frameworks that help us implement Dependency Injection. Today, we will look at Ninject (an IoC container) in a sample ASP.NET MVC Web application and understand the basics of DI using IoC.

dncmag
This article is published from the DNC Magazine – A Free High Quality Digital Magazine for .NET techies published once every two months.

This month's edition features hot topics like ASP.NET MVC4, SignalR, Knockout.js, jsRender, TDD, Visual Studio ALM, HTML5, SharePoint, Windows Azure and Metro Applications amongst others. Not to mention, a freewheeling interview with Ayende Rahien, the man behind RavenDB.

Download this Free Magazine Here

Before we jump into Ninject and Dependency Injection, let us quickly run through the basics of DI. The basic premises of DI are

  • All dependencies of a class should be passed (injected) into the class instead of being instantiated directly. In other words avoid new-ing up of interdependent layers.
  • Code to Interfaces instead of concrete implementations.
  • All Class instantiation and object lifecycle management should be done at a central location referred to as the ‘Composition Root’.
  • Inversion of Control (IoC) Containers refers to frameworks that help manage the object instantiation and lifecycle.
  • You can do DI without IoC containers, in such cases the pattern is referred to as ‘poor-man’s-DI’ and you have to hand code the object instantiation and lifecycle management.

 

A Simple Application

For the purposes of our discussion, we will take a simple three-layer application with one Entity on which we will be doing Create Read Update and Delete (CRUD) operations. A standard layering scheme looks like the following

hard-coupled-design

But in such a scheme, each layer instantiates the layer above it and the View layer access the Data Access Layer too. This is classic example of a hard coupled system.

Instead of the above, if we define the Data Access Interfaces in our Domain layer and implement those interfaces in the Data layer, the dependencies would get inverted and Data Layer would then be dependent on the Domain layer. The View layer continues to refer to the Domain layer. Since View layer doesn’t have access to EntityFramework or the Data Access Objects, how does it deal with the data? We define a layer of Plain Old CLR Objects (POCOs) in the Domain Layer. These POCOs are our Data Transfer Object (DTOs) between Data and Domain layers.

Since the Domain layer only defines Interfaces to the data layer (aka Repository Interfaces), there is nothing to new up in the View layer. The concrete instance of the Domain layer is passed in to the Domain layer. The concrete instance is created in the Composition Root.

Now our application layering looks as follows:

dependency-injection-design

 

How does this translate into code?

Well the sample application has the following structure.

The Data Layer

This layer has

  • POCOs used for serialization/deserialization of data from DB, using the EntityFramework. If case of other OR/M it will contain the Data Objects required by the OR/Ms.
  • The concrete implementation of the Repositories defined in the Domain Layer
  • The translation layer from Domain object to Data object and vice versa.

 

The Domain Layer

domain-layer

This layer has

  • The Interface definitions for all data access. Only the interfaced that are defined here is accessible to the view layer
  • The Domain POCOs
  • A Service Layer to manage business rules if any.

 

The View Layer

  • The view markup
  • The rendering logic
  • The Composition Root. For purposes of simplification, the Composition Root is shown in the View layer but as we will see later, this gives rise to a coupling that we will eventually have to break.

view-layer

 

A Closer Look at the Composition Root

Before we jump into an IoC container, lets take a closer look at the Composition Root.

composition-root-constructor

The Composition Root is essentially determining the concrete instance (SqlBlogPostRepository) for an interface (IBlogPostRepository), instantiating the concrete instance.

i-blogpost-repository

Next the code is fetching an instance of IControllerFactory that is responsible for generating all the controllers required in the MVC application. The Composition Root is also injecting the repository into the Controller Factory instance, thus making the Repository available for use in the View layer.

For a simple application as this sample, this discovery instantiating and injection looks trivial enough, but imagine a project with multiple controllers and repositories and other related dependencies, trying to track all of those manually and wiring them in the composition root will soon become a nightmare and devs in the team will start trying to hack their way around. This is where Inversion of Control Containers (or IoC Containers) comes into picture. IoC containers when configured to map an interface to a concrete type, can generate a new concrete instance whenever required. This automates the process of dependency wiring. As long as everyone is referring to Interfaces and the IoC container knows how to get a concrete class for that Interface, we are good. Ninject is once of the newer and popular IoC containers. It’s an open source project that is actively worked upon and has a vibrant community.

 

Getting Started with Ninject

Now that we have seen the code factored to use Poor Man’s DI, we will see how we can nicely transition to using Ninject and see the challenges on the way.

Installing Ninject

    - Select the web project

     - Open the (Nuget) Package Manager Console and use the following commands

            Install-package Ninject

     Install-package Ninject.MVC3

This installs the required dependencies for Ninject in an MVC application.

 

‘Configuring’ Ninject to be your IoC Container

Step 1: Open Global.asax and change the subclass from System.Web.HttpApplication to Ninject.Web.Common.NinjectHttpApplication

Step 2: Override the ‘CreateKernel’ method from the NinjectHttpApplication class in Global.asax and add the following

create-kernel-before

Step 3: Mapping the Dependencies.

- Add reference to FunWithSignalR.Data to your composition root (currently this is the web project don’t worry about the seemingly backwards dependency coupling, we will decouple it later).

- Create a new Class called DependencyMapper and inherit it from NinjectModule

- Override the Load() method and map the IBlogPostRepository to SqlBlogPostRepository as follows:

ninject-module

This code tells Ninject that whenever IBlogPostRepository is requested for, instantiate SqlBlogPostRepository with the given arguments in its constructor.

This method is where we will map similar dependencies when our project grows in size.

- Note how we pass constructor arguments to Ninject so that Ninject can use them at the time of type initialization.

- Setup the Application Start. Comment out the Application_Start() event’s code and add an override for the OnApplicationStarted method in the Global.asax

image

- If you run your application now, it will be up and running fine using Ninject IoC Container! W00t!

That covers up our migration from Poor Man’s DI to using Ninject as your IoC Container in ASP.NET MVC. For a sample project like ours, the benefits seem negligible but for larger projects having an IoC Container, the benefit goes a long way in helping manage object instantiation, Interface based development and therefore loosely coupled apps.

 

But… you just bunched all the references into the View layer!

Yes, you are right, and it’s a valid objection. If using IoC Containers and DI is the holy grail of decoupled application development, we just shattered that concept. The answer is rather simple. The ‘Composition Root’ of your application HAS to have access to all possible dependencies. Come to think of it, it’s a reasonable expectation. If it is going to be responsible for wiring up Interfaces to Concrete instances, it SHOULD know where to find the concrete instances.

IoC Containers support various ‘discovery modes’ for concrete instances. They are roughly bunched into

  • XML Configuration
  • Configuration via code conventions
  • Configuration via code

What we saw was Configuration via code. Ninject does not support an XML Configuration directly. The Extensions project help in that regard. We are not looking at these extensions today.

To solve our problem of having all references in the View layer, we will create a ‘Bootstrap’ project and add all references to that project. Then call the bootstrap from our Application start up. This way we can avoid the referencing issues.

 

Moving ‘Composition Root’ out of the Web Project

To solve our architectural issue of View layer referring to Data layer directly, we split the code up as follows:

1. Add a new ClassLibrary project and call it FunWithSignalR.CompositionRoot

2. Remove the default Class1.

3. Remove EntityFramework, FunWithSignalR.Data dependencies from the FunWithSignalRDI.Web project and add FunWithSignalR.Data and FunwithSignalRDI.Domain to the FunWithSignalR.CompositionRoot.

composition-root

4. Add Ninject dependencies to the CompositionRoot project by using the following command

install-package Ninject

Note you don’t need Ninject.MVC3 package here.

5. Move DependencyMapper.cs to the CompositionRoot project and update Namespaces are required

6. Add references to FunWithSignalR.Data, FunWithSignalR.Domain to the CompositionRoot

create-kernel-after

7. Add reference to System.Configuration.dll to the CompositionRoot.

8. Back in the Global.asax of the Web project, update the CreateKernel() method to include the CompositionRoot.

9. Remove the old BlogControllerFactory and CompositionRoot classes from the Web project.

10. Run the application. Voila! We have Ninject + ASP.NET MVC going like a charm.

Conclusion

We just scraped the surface of IoC Containers, specifically Ninject. We just resolved our repository types using the container. We could potentially extract interfaces for our Domain Entities and get the container to resolve them for us too.

Utility of the IoC Containers becomes quickly evident in very large projects.

For our well-experienced readers, hope this was a sufficient ‘quick-summary’. For our readers getting into DI and IoC we hope to have provided you with enough nudge to first adopt DI and next use IoC containers as a regular development practice.

Download the source code

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @sumitkm or email him at sumitkm [at] gmail


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Jacob on Friday, August 24, 2012 8:16 AM
Great article. Is there was a way to inject dependencies into custom ASP.NET controls?
Comment posted by Rajat on Monday, August 27, 2012 5:50 AM
While implementing Ninject in my MVC3 application between 2 classes, I get an error "A cyclical dependency was detected between the constructors of two services". How can resolve this issue.
Comment posted by Sumit on Monday, August 27, 2012 1:13 PM
@Jacob : Hi Jacob, Webform page lifecycle typically doesn't start with a Factory but there are various workarounds. Easiest is to use Castle Windsor or Sping.NET both are IoC containers. If they are not suitable, try this article, looked like a good approach. http://aspnetresources.com/articles/ioc_and_di_with_web_forms

@Rajat, If you have constructor of ClassA calling/referring to instance of ClassB and then Constructor of ClassB referring back to instance of ClassA you have a cyclic dependency. Check the classes that have the issues and remove dependency in the constructor atleast. Remember if you don't have a constructor variables that you are initializing globally will get initialized, so the same rules as above apply to those as well.
Comment posted by Sumit on Monday, August 27, 2012 1:15 PM
Okay, slight correction, webform page lifecycle doesn't start at a Factory is a miss-statement. Basically the workaround is to subclass the DEFAULT System.Web.UI.PageHandlerFactory.
Comment posted by Mike on Thursday, September 6, 2012 5:52 AM
Nice job. How could I download the source code, The Download link doesn't work.
Comment posted by Mike on Thursday, September 6, 2012 7:53 AM
Nice job. How could I download the source code, The Download link doesn't work.
Comment posted by Admin on Thursday, September 6, 2012 11:48 PM
Sorry Mike, the link has been fixed.
Comment posted by Sumit on Friday, September 7, 2012 7:20 AM
The download link points to the Github repo. On GitHub you have a 'Download Zip' link, to download entire codebase in one shot.
Comment posted by Akhilesh Gandhi on Tuesday, November 6, 2012 1:29 PM
How can I use Ninect with Repository pattern and UOW in Console application with Entity framework code first.
Comment posted by zbw911 on Tuesday, December 18, 2012 11:14 PM
Hi,Where the DataBase File?
Comment posted by Sumit on Wednesday, February 6, 2013 3:48 PM
[UPDATE]
The Ninject.MVC3 package has been updated to create a class called NinjectWebCommon in the App_Start folder. This class takes almost all the pain out of configuring Ninject. Changes are as follows

1. Don't have to inherit application from NinjectHttpApplication (Remove Step 1 above).
2. Instead of Step 2, use RegisterServices method in the NinjectWebCommon class to load assemblies into the Kernel.
3. In Step 8, update RegisterServices instead of Global.asax

With the new MVC3 module getting off the blocks with Ninject is really really easy.
Comment posted by siva on Friday, February 8, 2013 8:44 AM
Thanks Sumit, you have done a great job. very much appreciated and this article is useful to me and everybody.
Comment posted by Danilo on Wednesday, February 13, 2013 7:22 PM
I couldnt find the db file!

Comment posted by Sumit on Thursday, February 14, 2013 8:17 AM
Hi Danilo/zbw911 ,
Update the connection string in the web.config to point to a valid SQL Server (express will do).
EF should create the DB for you on the first run.
-Sumit.
Comment posted by Stefan Karlsson on Tuesday, January 7, 2014 2:54 PM
Thank you for a well writen tutorial.
Really helped me to get started with the DI partern.
Comment posted by subsci on Sunday, January 19, 2014 11:06 PM
Great job. In the sample code on GIT, I don't understand the apparent violation of the DRY (don't repeat yourself) principle: In both the Domain and the Data layers, the class, BlogPost is defined.  It is defined twice; with a conversion from the Data To Domain namespace defined in the Data layer version.  
Comment posted by Sumit on Tuesday, January 21, 2014 2:05 PM
Hi Subsci,

While the data Layer entity will always match the respective DB table (Properties mapped to columns etc.), the domain layer class in future can get more complex by composing other domain layer classes as Business logic demands.

So, for this simple example it looks like a violation of DRY, but it is also helping separate concerns of OR Mapping (in data layer) to the (foreseen) requirement of keeping business logic relatively independent of DB.

Hope this helps.
Sumit.
Comment posted by Jay Pondy on Saturday, January 25, 2014 3:17 PM
Thank you for a very well written and clear article on MVC and Ninject.  I noticed you applied the Data Annotations in the Domain.Model.BlogPost but not in the Data.Model.BlogPost so that they (Data Annotations) are surfaced in the Web views. This really helped to clarify the layers model for me and ease up my obsession with being so "data" oriented.  Thanks!!  Do you have an recommendations on what size project in terms of maybe table counts that this approach would start to pay dividends?