Sunday, December 19, 2010

Dependency Injection in ASP.NET MVC 3 using Ninject

Since the release of ASP.NET MVC 2, I am learning Dependency Injection in ASP.NET MVC. I used Microsoft Unity and realized the need for it to simplify ways to handle the dependencies between objects.

I have seen a lot of open source developers using Ninject as a dependency injector and I think I’ll give it a try. In Rob Conery’s MVCStarter, I have seen good implementation of IoC setup using Ninject 2.0 it was good but I have too many works done in MVC application’s Global.asax.cs file. I didn’t like that configuration but I’ve no choice.

With the release of ASP.NET MVC 3 BETA [currently in RC 2] they have made significant changes to the IoC support, please look at Brad Wilson's post, for service location/dependency resolution with MVC, they introduced new interface: System.Web.Mvc.IDependencyResolver. You have to implement this interface within your application and register it with System.Web.Mvc.DependencyResolver’s static method SetResolver(IDependencyResolver resolver).

In Scott Guthrie's post, I have downloaded and study the Ninject implementation of dependency injection and happy with the neat code he wrote. no use of Ninject MVC extension: Ninject.Web.MVC, it is due to the new IoC support in ASP.NET MVC 3.

There are some questions asked regarding it on stackoverflow, So I decided to write a brief post on how to use Ninject 2 in ASP.NET MVC 3.

Prerequisites

you will need to download the latest build of Ninject from here. I download this Ninject-2.1.0.91-RC2-release-net-4.0.zip. You also need the latest release of ASP.NET MVC 3 [RC 2]. If you download the project at the end of this post then you don’t need to download Ninject binaries it’s been provided in the project itself.

Let’s start

Create new project: File –> New –> Project

You can download the ready to run project at the end of this post.

Select ASP.NET MVC 3 Web Application as shown below:

New MVC 3 Web Application

After clicking OK you would see new ASP.NET MVC 3 Project dialog asking you to select Template, View Engine and you want Unit Test project or not.

New project dialog

Now you have your new ASP.NET MVC 3 Web Application project ready.

For demonstrating dependency injection we need some sort of interfaces and their concrete implementations, so in that regard I will add a new interface named IMessageService and it’s implementation MessageService in the new Services folder to the project root.

Here is the interface IMessageService:

IMessageService

and MessageService:

MessageService

Now setting up project to introduce dependency injection, this is the time to add a reference to Ninject.dll that you have downloaded as described earlier, if you are lazy like mine then download the project linked at the end of this post.

Now open up Global.asax.cs and add the using Ninject; statement to add a Ninject reference, from ASP.NET MVC 3 Beta and above we have to implement IDependencyResolver for DI work, so It can be implement like this:

IDependencyResolver

Now in the Application_Start(), we want to hook our DI related stuff. for simplicity, like Scott Guthrie did, I’ll add a method which do it all like that:

SetupDI

ok, in the method above I created a standard kernel which is implemented in the Ninject.dll and bind our service to it’s concrete implementation, say whenever the application encounters the IMessageService then it will automatically creates a new instance of MessageService damn simple isn’t it, don’t forget to call above method in Application_Start().

To test it, open up HomeController and change it like that:

HomeController

First, I add a private readonly field _messageService that holds our service instance on the fly. I also add a class constructor which takes single parameter of type IMessageService and then set it to our private field.

In Index() ActionResult method I called the GetMessage() and we are done, look I didn’t create a new instance of MessageService class anywhere it will automatically created by our DI container.

Now run your application by pressing F5 or Ctrl+F5 you will see:

Run

you see the message above it comes from our MessageService class’s GetMessage() method which I called in HomeController.

Hope you understand how DI works in ASP.NET MVC 3 with Ninject without the need of Ninject.Web.Mvc extension, thanks to the Phil Haack and team.

Now for your comfort, download the ready to run project right now.

Note: I have been learning coding best practices since my early development years, so if you found that I made a mistake here and there then please express it in comments below, I appreciate that and will learn from you.

Enjoy!

28 comments:

  1. Note: the download requires creation of a virtual directory with port 2550 to be configured in IIS. On running the site I get Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.. Though. ho hum

    ReplyDelete
  2. Hello Damian, The project was configured to run with IIS Express 7.5 Beta 3 and not with the VS Development Server [Cassini], I've changed it back to Cassini, please download it once again and open the solution file and run from the Visual Studio itself. The requirements of the project is VS 2010 [Any SKUs like Express, Pro, Pre and Ultimate] and ASP.NET MVC 3 RC 2 and please make sure you have it all, However I've VS 2010 SP1 Beta installed on my machine. If problem persists then please let me know I'm here to help you.

    Sorry for any inconvenience made to you.

    Thanks!

    ReplyDelete
  3. @Shahnawaz - just downloaded and runs fine with Cassini. Well done, just the example I was searching for.

    ReplyDelete
  4. IMO much better solution than NInject extension, good job on this article mate!

    ReplyDelete
  5. Great article!! Just one comment, I think you missed to show the sample code where you call SetupDependencyInjection() in Application_Start? It would make the article perfect ;)

    ReplyDelete
  6. Thank you! I just spend 2 hours trying to find an up to date article on Ninject integration with MVC 3. This was exactly what I was looking for. I think Ninject need to put together some documentation....

    ReplyDelete
  7. Finally a tutorial that shows how to use ninject in asp.net mvc 3

    ReplyDelete
  8. Excellent post. Thank you.

    ReplyDelete
  9. Since you are using MVC3, why not just use NuGet. There is a NuGet package called Ninject.MVC3. All you have to do is install it and it adds the references, modifies web.config and even adds in a class that implements IDependency resolver. You can add ninject support within seconds using NuGet.

    ReplyDelete
  10. Thanks for this post - A good explanation of what is required for MVC3 and DI\Ninject

    ReplyDelete
  11. Very very useful. Helped me a lot. Thanks a bunch !!!

    ReplyDelete
  12. Very useful....

    Thanks

    ReplyDelete
  13. Shahnawaz,
    I wonder if you have figured out how to use DI and Ninject with a bootstrapper with a multi-assembly solution. If so could you provide an example? This would be a little more advanced than your example above but it's the actual way it would be used in real world development. 

    ReplyDelete
  14. CD Smith I wrote this post when there was no option for me to use Ninject in MVC and i want full control in every aspects, and MVC 3 was in Beta so the things has changed, now it's very easy to do all stuffs, just use Nuget to get Ninject.MVC3 and you are good to go. I'll post this in my next article.

    ReplyDelete
  15. This is still one of the best Ninject starting guides for MVC3! Great job and very well explained!

    ReplyDelete
  16. Thanks! A good quick to the point example.

    ReplyDelete
  17. Nice job. For those looking at separating out abstraction to concrete mapping, google ninject assembly scanning and modules.

    ReplyDelete
  18. This article is really wonderful and it is one of the best out there for a beginner.

    Thank you

    ReplyDelete
  19. Great! Clear and straightforward! Thank you.

    ReplyDelete
  20. Do you have any plans to update this post for the newest version of NInject 3? Also it would be incredibly helpful for you to show multi-project solution with a composition root 'outside' of the UI project as in real world usage we don't want any hard references in the UI project, only in the composition root where the binding is taking place

    ReplyDelete
  21. Hey, just wanna say thanks for this post

    ReplyDelete
  22. This is really very good post which will help beginner to lean quickly.Thanks..

    ReplyDelete
  23. I also just spend time trying to find an up to date article on Ninject integration with MVC 3. This was exactly what I was looking for. I think Ninject need to put together some documentation..

    ReplyDelete
  24. After reading multiple Ninject and DI tutorials, this one finally made me understand all of it. Nice and concise, clear code examples, WELL DONE! Thanks so much.

    ReplyDelete
  25. It's a shame you don't have a donate button! I'd certainly donate to this superb blog!
    I guess for now i'll settle for book-marking and adding your RSS feed to my Google account.
    I look forward to new updates and will share this website with my Facebook group.
    Talk soon!

    gold ira investing

    ReplyDelete

Thanks for posting valuable comments, your comments will be reviewed before publishing.