Tuesday, December 14, 2010

Ninject with ASP.NET MVC 3…Easy As 1, 2, 3

  1. Add references to Ninject.dll and Ninject.Web.Mvc.dll (You can use NuGet to add Ninject, but for now you’ll have to download and build Ninject.Web.Mvc yourself).
  2. Create 1 or more modules:

    public class MyModule : NinjectModule
    {
        public override void Load()
        {
            Bind<IFoo>().To<Foo>();
        }
    }
    
  3. Make your HttpApplication (typically global.asax.cs) extend NinjectHttpApplication and override the CreateKernel() method:

    public class MvcApplication : NinjectHttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }
    
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
            routes.MapRoute(
                "Default",
                "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    
        protected override void OnApplicationStarted()
        {
            base.OnApplicationStarted();
    
            AreaRegistration.RegisterAllAreas();
    
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }
    
        protected override IKernel CreateKernel()
        {
            return new StandardKernel(new MyModule());
        }
    }

That’s it.  Now you’re all set to go, even your controllers will be created with Ninject which means all of their dependencies will be resolved using your Module(s).

5 comments:

funky said...

This code doesnt works. It even doesnt called Application_Start function in Global.asax.cs

I already use the latest NInject library

MrDustpan said...

@funky - Make sure you have all of the following in place and it should work for you:

- Use ASP.NET MVC 3 (RC2)
- Latest Ninject
- Latest Ninject.Web.Mvc (download from github and build it)
- Your global.asax.cs class needs to derive from NinjectHttpApplication
- Inside your global.asax.cs override the OnApplicationStarted() method.

bigThump said...

I just installed the Ninject.MVC3 package from nuget. I didn't have to build anything. It installed a class called "AppStart_NinjectMvc3" which uses WebActivator to instantiate itself "pre-application-start" and you can put your bindings right in the RegisterServices() method. Then a call to DependencyResolver.SetResolver(new NinjectServiceLocator(kernel)); (which is built into the class already) takes care of rocking out the connections to the controller, so constructor injection just works, easy as 1,3.

My question is, what does Ninject.Web.Mvc offer that the approach above does not? Did I strike gold, or am I missing something?

bigThump said...

Oh, btw, given that the Ninject.MVC3 hooks into the ServiceLocator stuff (that I am still reading up on), I was able to hook into my custom MembershipProvider implementation with:

_repo = DependencyResolver.Current.GetService(typeof (IRepository)) as IRepository;

I thought that was pretty slick, but again, idk if i'm missing something or not.

MrDustpan said...

@bigThump, I don't think you're missing anything at all. I haven't looked into the Ninject.MVC3 or MVC3 Service Locator stuff yet, but it sounds like a pretty slick solution. I'll have to look into that and see if it's easier/better.

I am currently using Ninject.Web.Mvc because I've used it before and am somewhat familiar with it. I also received confirmation from the Ninject.Web.Mvc guys that they're going to add it to NuGet once their next version is done.