First time here? You are looking at the most recent posts. You may also want to check out older archives or the tag cloud. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS. Thank you for visiting! (hide this)

Back in February I wrote a series of posts about Ninject and ASP.NET MVC, and how to adapt Ninject v1 to inject dependencies into ActionFilter. Now that Ninject 2 reached the Beta status and a final release could be on its way, I think the time has come to to update the article. So in this post you’ll learn how to use Ninject v2 to inject dependencies into ASP.NET MVC controllers and action filters.

What’s new in Ninject 2

Ninject 2 has been rewritten from scratch, trimmed down a lot, many non-core features removed, and a plugin/extension model has been introduced. You can read more details about the new features on Nate’s blog. The main change that impacts the integration with ASP.NET MVC is that it is now in its own project, called Ninject.Web.Mvc, and that it now includes filter injections by default. So no more need of the small utility I developed to support injection into ActionFilters.

Where to get Ninject 2

Ninject v2 has not been released yet: the sample on this post is based on the official beta released by Nate, but if you want you can download the latest source code directly from the repository online:

The zip files are just the dump of all the tree in the repository. Once you download them, you have to extract and then build the two project.

But if you don’t want to go through all that process, the code sample attached to this post contains the beta version of Ninject core and of the ASP.NET MVC extension.

Application code

This sample is just going to be the port of the sample I wrote for Ninject v1:

  • Controller that calls an external service to get the Greeting
  • Actions decorated with the attribute that sets the title of the page
  • View that shows the greeting to the user

For your convenience here are some snippets with the parts of the code that are relevant for the sample.

The external greeting service

First is the external service, which returns the greeting to the visitor of the site

public class GreetingServiceImpl : IGreetingService
{
    public string GetGreeting()
    {
        return "Hello from the Greeting Service concrete implementation!";
    }
}

public interface IGreetingService
{
    string GetGreeting();
}

The HomeController

What the controller does is just calling the service and putting the greeting returned inside the view model. Also the action is decorated with an ActionFilter that sets the title of the page, always retrieving it from the same greeting service.

public class HomeController : Controller
{
    private readonly IGreetingService _service;
    public HomeController(IGreetingService _service)
    {
        this._service = _service;
    }

    [TitleActionFilter]
    public ActionResult Index()
    {
        ViewData["Message"] = _service.GetGreeting();
        return View();
    }
}

The action is decorated with the TitleActionFilter attribute

The TitleActionFilterAttribute

public class TitleActionFilterAttribute : ActionFilterAttribute
{
    [Inject]
    public IGreetingService _service { get; set; }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        ViewResult result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.ViewData["Title"] += _service.GetGreeting();
        }
    }
}

The property that contains the reference to the external service, and that will injected via Ninject, is decorated with the [Inject] attribute

The view

And finally the view, whose only purpose is displaying the message to the user and setting the title of the page.

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    <%= Html.Encode(ViewData["Title"]) %>
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
</asp:Content>

But now let’s have a look at how to setup Ninject v2 with ASP.NET MVC

Wiring up Ninject

Since version 1 and even 1.5, a lots of improvement were added, so the steps for setting up Ninject in an ASP.NET MVC project with support for injection into ActionFilters went down to just 2:

  1. Add the references to Ninject and Ninject.Web.Mvc
  2. Setting up the container inside the Global.asax.cs file

Let’s see each one of these steps.

referencesAdding references

After you downloaded the assemblies or compiled the source from GitHub, you have to add the two assemblies are references:

  • Ninject
  • Ninject.Web.Mvc

Copy them into a folder inside your solution and add the references.

Setting up the container

This step is the one that differs the most from version 1.5 of Ninject.

You still have to inherit from NinjectHttpApplication instead of HttpApplication, but the way you register the controllers is different.

Here is the complete code of the Global.asax.cs file:

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        //Here goes routing setup
    }

    protected override void OnApplicationStarted()
    {
        RegisterRoutes(RouteTable.Routes);
        RegisterAllControllersIn(Assembly.GetExecutingAssembly());
    }

    protected override IKernel CreateKernel()
    {
        return new StandardKernel(new ServiceModule());
    }
}

internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind<IGreetingService>().To<GreetingServiceImpl>();
    }
}

All the initialization code of the web application, the one that would normally go into the Application_Start method, now has to go into the OnApplicationStarted one. Inside this method goes the setup of the routing table and the call to the method that registers all the controllers of the application.

RegisterAllControllersIn(Assembly.GetExecutingAssembly());

This method scans all the types inside the assembly supplied, and registers for injection all the controllers it finds.

The Ninject Application class also makes easier creating and configuring the kernel, through the CreateKernel method.

And what about the ActionFilters?

You might wonder where all the configuration needed for injecting dependencies inside action filter went. The cool thing about Ninject 2 is that this kind of injection comes out of the box with the ASP.NET MVC extension. So the only line of code needed it the [Inject] attribute applied to the property of the action filter that will hold the injected dependency. Cool, isn’t it?

What’s next

Ninject v2 is looking very stable, and I’ve used it in production code, and didn’t give me any problem, so I really encourage you download the latest bits, and play around with it.

If you want to try this by yourself, I packaged the sample into a VisualStudio 2008 solution that you can download

kick it on DotNetKicks.com

posted on Friday, August 14, 2009 2:55 PM

Comments on this entry:

# re: How to use Ninject 2 with ASP.NET MVC

Left by Robert at 8/16/2009 4:25 AM

I switched from Ninject 1.0 to 2.0 in a web project and each page processing time went from 20ms to 60ms. Have you experienced anything similar? I'm wondering if that's expected or if I'm doing something wrong.

# re: How to use Ninject 2 with ASP.NET MVC

Left by ITmeze at 8/16/2009 6:20 PM

I was using StructureMap in my recent project. I really liked it's "feature" to cache object for the duration of http context during registration, like:
ForRequestedType().CacheBy(InstanceScope.HttpContext);
That was really helpful, and easy.
How can I "copy" this feature to using Ninject lib? Can I use Ninject in medium trusted environment? There are some problems with StructureMap - (it's calls to some reflection methods).

# re: How to use Ninject 2 with ASP.NET MVC

Left by uzivatel at 8/19/2009 12:10 AM

well inheriting from NinjectHttpAplication smells for me, but it is just me, all the others can be fine with it...

I don't see much simplification here, I'm using container which is even less verbose...

# re: How to use Ninject 2 with ASP.NET MVC

Left by Simone at 8/23/2009 2:47 PM

@ItMeze: in Ninject v2, to "cache" the result of an injection per HttpRequest you can do:

Bind().To().InRequestScope();

This is one of the possible way of injection, together with InSingletonScope, InTransientScope and InThreadScope.

Tt was a bit different in Ninject 1, refer to Ninject documentation if you are using Ninject 1 dojo.ninject.org/Activation%20Behaviors.ashx

# re: How to use Ninject 2 with ASP.NET MVC

Left by ITmeze at 8/24/2009 3:27 PM

@Simone - thanks, exactly what i was looking for.

# re: How to use Ninject 2 with ASP.NET MVC

Left by simone romano at 8/31/2009 6:25 PM

does not work for me:
I have a very simple controller with an action "Index" with a nullable id parameter. When the application gets loaded with the defaults, ok, the id is null, but when I call (from action links or from browser address bar either) e.g. http://localhost:/controller/index/3 the id parameter never assumes the value 3. What's wrong?
thanks

# re: How to use Ninject 2 with ASP.NET MVC

Left by Paul at 9/13/2009 1:45 PM

@uzivatel - I agree with you, but just take a look at the code for NinjectHttpApplication; it's pretty easy to remove the need for it by rolling your own NinjectControllerFactory

# re: How to use Ninject 2 with ASP.NET MVC

Left by Mark at 10/16/2009 3:12 AM

Simone,

First off thanks for the great series of posts.

Do you know how to use the fluent interface to specify property binding in Ninject 2? Your previous Ninject 1 example used:

Bind().ToSelf().InjectPropertiesWhere(p => p.Name == "Service");

InjectPropertiesWhere() does not appear to be available in Ninject 2. Is it still possible?

Mark

Comments have been closed on this topic.