Ninject.Web.MVC + MVC3 throws StackOverflowException

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.


    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.


    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

    链接地址: http://www.djcxy.com/p/49078.html

    上一篇: 在Eclipse(Helios)中设置项目Pydev PYTHONPATH的最有效方法是什么?

    下一篇: Ninject.Web.MVC + MVC3抛出StackOverflowException