7

I've got a simple web application using ASP.NET MVC3 and Ninject.Web.MVC (the MVC3 version).

The whole thing is working fine, except when the application ends. Whenever it ends, the kernel is disposed, as seen in Application_End() in NinjectHttpApplication:

Reflector tells me this:

public void Application_End()
{
    lock (this)
    {
        if (kernel != null)
        {
            kernel.Dispose();
            kernel = null;
        }
        this.OnApplicationStopped();
    }
}

What happens is that my webserver goes down with a StackOverflowException (I tried both IIS7 and the built-in webserver in VS2010). I can only assume this is where it's going wrong, as I haven't written any code myself on application end.

I figured out that the Kernel knows how to resolve IKernel (which returns the Kernel itself), might this be something that could cause the stack overflow? I could imagine something like this happens:

  • Kernel.Dispose()
  • Dispose all instances in the kernel
  • hey! look at this, the kernel is also in the kernel. Return to step 1.

In other words, the kernel gets disposed, disposes all references it holds (which includes a self-reference), which causes it to dispose itself.

Does this make any sense?

Edit:

It seems the problem is in NinjectHttpApplication. Take a look at this activation code:

    public void Application_Start()
    {
        lock (this)
        {
            kernel = this.CreateKernel();
            ...
            kernel.Bind<IResolutionRoot>().ToConstant(kernel).InSingletonScope();
            ...
        }
    }

It seems ok, but what's happening now is that whenever an IResolutionRoot is called, kernel is cached within itself. When disposing the kernel, the cache is emptied which disposes all cached objects, which causes a circular reference.

A simple solution for NinjectHttpApplication would be to simply change the binding. Change the constant binding to a method one:

kernel.Bind<IResolutionRoot>().ToConstant(kernel).InSingletonScope();

becomes

kernel.Bind<IResolutionRoot>().ToMethod(x => this.Kernel);

This solves the problem, but I am not sure if the whole circular dispose caching issue is a bug in ninject.

1
  • 1
    I recommend your post your edit as an answer to supplement mine. Commented Dec 1, 2010 at 20:15

2 Answers 2

2

I encountered the same issue.

I ended up copying the code for NinjectHttpApplication and removing Kernel.Dispose() in the Application_End function.

public void Application_End()
{
    lock (this)
    {
        if (kernel != null)
        {
            //kernel.Dispose();
            kernel = null;
        }
        this.OnApplicationStopped();
    }
}

That should fix the error. Not sure if there is a planned fix for it though.

Sign up to request clarification or add additional context in comments.

2 Comments

It's acceptable, MVC3 is still in preview, so I can't assume something derived like Ninject.Web.MVC to be fully functional either.
I'm looking into the details now, trying to create a real fix instead of simply not disposing my kernel. Accepted your answer because it works.
2

There was a bug in MVC3. It's fixed in the latest revision and will be part of the RC2 comming next week. In the mean time take the build from the build server http://teamcity.codebetter.com

4 Comments

This problem has been driving me nuts for two weeks! :) I have even been back and forth with the ASP.NET MVC dev team trying to determine if this was an MVC 3.0 RC issue they needed to be aware of, or Ninject. Thanks for the fix; I will try it now.
So far so good Remo, no web server crashes. But I still receive a StackOverflowException when editing un-checked out files (Causing them to checkout) while the app is running, such as a site's .css file. Don't ask me why :) But I receive a "No Source Available" error on a white screen with the following call stack, you can see still we are hitting a circular-dependency somewhere: pastebin.com/Jk83stxW
Sry I can't follow, what you are doing. Please describe it more precisely or provide a sample application showing the problem.
Either way, the solution I posted works as well. I did use the version from the build server, but it might be that I had the previous version? Either way, the solution I posted works so far, so I'll just keep that in until MVC3 RC2 is released.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.