我们已经设置了一个WCF服务,该服务使用Unity容器来解析用于管理Exchange 2010 Powershell命令的实例。我们定义了一个IExchangePowershell接口,它有一个实现IDisposable的具体实现。一段时间后,我们遇到了无法执行powershell命令的问题,因为服务器说已经有太多的PowerShell会话打开了。似乎我们从未真正处理过我们的powershell实例。具体的Powershell的Dispose()方法将负责关闭运行空间和会话。一旦我在存储库方法中调用它,我们就不会再出现错误了。
((IDisposable)this.powershell).Dispose();
现在我当然不希望在每个存储库方法中显式调用dispose。我认为团结可以解决这个问题。我们的WCF实例提供程序执行此操作:
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
container.Teardown(instance);
}
但这并没有真正处理IExchangePowershell实例。你知道如何自动处理这些实例吗?
答案 0 :(得分:10)
这实际上是Unity中众所周知的问题。 TearDown
方法does nothing。如果要使用TearDown
,则必须创建自定义容器扩展。
我写了一篇article关于在Unity中使用对象生命周期管理器及其对处置的影响。如果您使用默认TransientLifetimeManager
或PerResolveLifetimeManager
,Unity甚至不会跟踪您的对象的存在,因此无法调用Dispose
。在已解析的实例上调用Dispose
的唯一终身经理是ContainerControlledLifetimeManager
(也称为单身人士)和HierarchicalLifetimeManager
。处置生命周期管理器时会调用Dispose
。
您的解决方案是手动使用强制转换和处理Dispose
,或者切换到HiearchicalLifetimeManager
并为每个传入的WCF请求创建新的子容器。每个子容器只处理单个请求,它将处理具有层次生命周期的已解析实体。
还有其他方法,例如this article围绕Unity构建一个非常复杂的代码,以支持对所有已解析对象的处理和TearDown
。
答案 1 :(得分:0)
答案取决于您如何统一注册您的类型/实例。 Teardown的标准实施完全没有做任何事情。
如果你注册了类型,那么Unity不存储对它创建的实例的引用 - 由你来管理它的生命周期并处理它。如果您注册实例,则实例生命周期由unity统一管理,并保留到您处置容器为止。
以下链接有助于更好地了解终身管理: http://msdn.microsoft.com/en-us/library/ff648098.aspx
你需要问自己何时你希望你的对象被处理掉。如果您知道何时调用ReleaseInstance,您也可以调用IDispose而不是它。
(对不起,我不熟悉WCF,所以我不确定在这种情况下提供的是什么实例)