views:

920

answers:

1

I just did File -> New Project last night on a new project. Ah, the smell of green fields.

I am using the just released ASP.NET MVC 2 (i.e. no preview or release candidate, the real thing), and thought I'd get off to a good start using Ninject 2 (also released version) with the MVC extensions. I downloaded the MVC extensions project, opened it in VS2008Sp1, built it in release mode, and then went into the mvc2\build\release folder and copied Ninject.dll and Ninject.Web.Mvc.dll from there to the Libraries folder on my project (so that I can lug them around in source control and always have the right version everywhere). I didn't include the corresponding .xml files - should I? Do they just provide intellisense, or some other function? Not a big deal I believe.

Anyhoo, I followed the most up-to-date advice I could find; I referenced the DLLs in my MVC2 project, then went to work on Global.asax.cs. First I made it inherit from NinjectHttpApplication. I removed the Application_Start() method, and overrode OnApplicationStarted() instead. Here is that method:

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

And I also followed the advice of VS and implemented the CreateKernel method:

protected override Ninject.IKernel CreateKernel() 
{ 
    // RegisterAllControllersIn(Assembly.GetExecutingAssembly()); 
    return new StandardKernel(); 
} 

That is all. No other modifications to the project.

You'll notice that the RegisterAllControllersIn() method is commented out in two places above. I've figured I can run it in three different combinations, all with their funky side effects;

  • Running it like above.

I am then presented with the standard "Welcome to ASP.NET MVC" page in all its' glory. However, after this page is displayed correctly in the browser, VS shows me an exception that was thrown. It throws in NinjectControllerFactory.GetControllerInstance(), which was called with a NULL value in the controllerType parameter. Notice that this happens after the /Home page is rendered - I have no idea why it is called again, and by using breakpoints I've already determined that GetControllerInstance() has been successfully called for the HomeController. Why this new call with controllerType as null? I really have no idea. Pressing F5 at this time takes me back to the browser, no complaints there.

  • Uncommenting the RegisterAllControllersIn() method in CreateKernel()

This is where stuff is really starting to get funky. Now I get a 404 error. Some times I have also gotten an ArgumentNullException on the RegisterAllControllersIn() line, but that is pretty rare, and I have not been able to reproduce it.

  • Uncommenting the RegisterAllControllers() method in OnApplicationStarted()

(And putting the comment back on the one in CreateKernel())

Results in behavior that seems exactly like that in point 1.

So to keep from going on forever - is there an exact step-by-step guide on how to set up an MVC 2 project with Ninject 2 (both non-beta release versions) to get the controllers provided by Ninject? Of course I will then start providing some actual stuff for injection (like ISession objects and repositories, loggers etc), but I thought I'd get this working first.

Any help will be highly appreciated!

(Also posted to the Ninject Google Group)

+8  A: 

I feel dirty answering my own question, but for the benefit of anyone who might wander into this...

This is not a Ninject problem, really, it seems to be an issue with Cassini (the web server built into VS2k8), which handles these requests differently than IIS would handle them. The basic reason is that the app gets a request for favicon.ico, which Cassini sends to MVC, and Ninject didn't know how to handle it.

Ian Davis had a bug fix for this out in an impressively short amount of time, and also recommended to add an ignore route to avoid this problem specifically while doing development. Just add the following to your route config:

routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

Hope this helps someone!

Rune Jacobsen