Search code examples
asp.net-mvcunity-containerstack-overflow

Do I really need to dispose IUnityContainer on shutdown of application


I'm maintaining code for a web application built using Asp.NET MVC. An MVC dependency resolver has been implemented using Unity container. Here's the cleanup code that's called on application shutdown.

 public static void Shutdown()
 {            
        IUnityContainer container = UnityConfig.GetConfiguredContainer();
        container.Dispose(); //currently when called causes stack overflow            
 }

The issue we're having is that during a shutdown the call to dispose (above) causes a stack overflow exception and then the process crashes because of it. This also occurs during development when debugging the app and making changes to web.config (since changes to web.config seems to restart the application) which also stops the debugging session which normally shouldn't end. No stack overflow seems to occur if I remove the call to dispose, and the application then exits or restarts normally without the process crashing during debugging sessions.

I'm thinking of simply permanently removing the call to Dispose but I'm uncertain of the consequences, wouldn't an application shut down inevitably lead to the disposing of the container anyway?

If removing the call to dispose is not recommended then the only option would be to find the real cause which I believe lie in a circular dependency within the container itself, but I can't find it, how should I debug this issue ?


Solution

  • The cause of the stackoverflow is infinite recursive call to Dispose of UnityContainer, which I think is (weirdly) caused by the automatically registered IUnityContainer which is not managed by our code and should be handled in unity library. I was able to stop the infinite recursion simply by swapping out the usage of the UnityContainer class with a derived class that override Dispose and returns on a recursive call:

    public class CustomUnityContainer : UnityContainer
    {
    
        private bool inDispose = false;
    
        protected override void Dispose(bool disposing)
        {
            if (inDispose) //prevents recursive calls into Dispose
                return;
    
            inDispose = true;
    
            base.Dispose(disposing);
    
            inDispose = false;
    
        }
    }