Ninject with ASP.NET MVC series
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:
- Add the references to Ninject and Ninject.Web.Mvc
- Setting up the container inside the Global.asax.cs file
Let’s see each one of these steps.
Adding 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