I have a simple wrapper for a Unity IoC container (a temporary use of Service Locator [anti-]Pattern to introduce DI to a legacy codebase), and since the IUnityContainer
in Unity implements IDisposable
I wanted to expose that through the wrapper as well.
The wrapper is simple enough:
public class IoCContainer : IIoCContainer
{
private IUnityContainer _container;
public IoCContainer(IUnityContainer container)
{
_container = container;
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~IoCContainer()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
if (_container != null)
{
_container.Dispose();
_container = null;
}
}
}
IIoCContainer
is the domain interface which has nothing but T Resolve<T>()
on it, and of course IDisposable
. So everything below that one method is simply the implementation of IDisposable
as I found it on MSDN.
However, when .Dispose()
is called on this object (such as when exiting a using
block), a StackOverflowException
is raised. Debugging, it looks like the call stack repeats between:
Dispose()
is called on this class- Which calls
Dispose(true)
on this class - Which calls
Dispose()
onIUnityContainer
- Which calls
Dispose()
on this class
I can resolve this in this case by putting a bool
flag on the class, setting it on the first line of Dispose()
, and checking for it in Dispose(bool)
, so the recursion ends at its second iteration. But why does this happen in the first place? I can only assume I've either missed something obvious or misunderstood something about resource disposal. But what?
This is implementation of
IDisposable
withinUnityContainer
. It is obvious that you cannot dispose your parent container. It will iterate through all registrations and dispose them if they are alsoIDisposable
. Take a look: