我有一个用于 Unity IoC 容器的简单包装器(临时使用服务定位器 [anti-]Pattern 将 DI 引入遗留代码库),并且自 IUnityContainer
在 Unity 中实现 IDisposable
我也想通过包装器公开它。
包装器非常简单:
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
是域接口(interface),它只有 T Resolve<T>()
在上面,当然还有IDisposable
.因此,该方法下面的所有内容都只是 IDisposable
的实现。 as I found it on MSDN .
然而,当.Dispose()
在此对象上调用(例如退出 using
block 时),一个 StackOverflowException
被提出。调试,看起来调用堆栈在以下之间重复:
-
Dispose()
在这个类上被调用 - 调用
Dispose(true)
在这门课上 - 调用
Dispose()
在IUnityContainer
- 调用
Dispose()
在这门课上
在这种情况下,我可以解决这个问题,方法是放置 bool
类上的标志,将其设置在 Dispose()
的第一行,并在 Dispose(bool)
中检查它, 所以递归在它的第二次迭代结束。但是为什么首先会发生这种情况?我只能假设我错过了一些明显的事情或者误解了有关资源处理的事情。但是什么?
最佳答案
这是 UnityContainer
中 IDisposable
的实现。很明显,您不能处置您的父容器。它将遍历所有注册并在它们也是 IDisposable
时处理它们。看一看:
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (lifetimeContainer != null)
{
lifetimeContainer.Dispose();
lifetimeContainer = null;
if (parent != null && parent.lifetimeContainer != null)
{
parent.lifetimeContainer.Remove(this);
}
}
extensions.OfType<IDisposable>().ForEach(ex => ex.Dispose());
extensions.Clear();
}
}
关于c# - 处理托管资源时堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41286181/