The NHibernate 3 Music Store – IoC with Ninject – Part 5
28 August 2010
At the end of the last post I was deciding whether to use IoC to manage my new dependency on an IMusicStoreContext. I could have made a call to the static MvcApplication.GetCurrentRequestContext(), but from an architectural point of view, that would be tightly coupling a class to another concrete resource – which is a bad design choice for testability, maintainability and malleability.
To keep the code clean, I’m going to change things around a bit to use an IoC container. I’ve read about the Ninject.Web.Mvc project and I’d like to learn how to use it, so here we go :)
I’ve downloaded and built the Ninject.Web.Mvc project, it’s now part of the lib folder in my project’s GitHub repo as well.
The Ninject MVC project provides a NinjectHttpApplication abstract class that we’ll inherit from instead of the System.Web.HttpApplication on our MvcApplication class. We’ll also override the CreateKernel() method on the NinjectHttpApplication.
public class MvcApplication : NinjectHttpApplication
{
...
protected override IKernel CreateKernel()
{
return new StandardKernel(new MusicStoreNinjectModule());
}
}
The Application_Start() method must be renamed to override the OnApplicationStarted method – or you can add an event binding to it in the constructor. The NinjectHttpApplication doesn’t execute the Application_Start method by default as the standard HttpApplication does.
And we’ll create the MusicStoreNinjectModule to resolve our controllers and our IMusicStoreContext like this:
public class MusicStoreNinjectModule : NinjectModule
{
public override void Load()
{
Bind<AccountController>().ToSelf();
Bind<CheckoutController>().ToSelf();
Bind<HomeController>().ToSelf();
Bind<ShoppingCartController>().ToSelf();
Bind<StoreController>().ToSelf();
Bind<StoreManagerController>().ToSelf();
// This will be injected into our controller to give us access to our context
// without introducing a tight coupling to a static resource.
Bind<IMusicStoreContext>().ToMethod(c => MvcApplication.GetCurrentRequestContext());
}
}
That means I can now add a constructor to each of our controllers that accepts an IMusicStoreContext and our controller will always receive a context object that’s built for the active request.
Neat :) Again, the code’s all on GitHub.