2011-04-20 36 views
6

我們已經設置了一個WCF服務,該服務使用Unity Container來解析用於管理Exchange 2010 Powershell命令的實例。我們定義了一個具有實現IDisposable的具體實現的IExchangePowershell接口。一段時間後,我們遇到了問題,我們無法執行powershell命令了,因爲服務器說已經有太多的PowerShell會話打開了。看來,我們從來沒有真正處理過我們的PowerShell實例。具體Powershell的Dispose()方法將負責關閉運行空間和會話。一旦我在存儲庫方法中調用它,我們不會再有錯誤了。WCF,Unity:拆卸一次性實例

((IDisposable)this.powershell).Dispose(); 

當然現在我不想顯式調用部署在每一個存儲庫的方法。我認爲團結可以照顧這一點。我們的WCF實例提供這樣處理:

public void ReleaseInstance(InstanceContext instanceContext, object instance) 
{ 
    container.Teardown(instance); 
} 

但是,這並沒有真正處置IExchangePowershell實例。你有什麼想法我可以自動處理這些實例嗎?

回答

10

這實際上是Unity中衆所周知的問題。 TearDown方法does nothing。如果您想使用TearDown,則必須創建自定義容器擴展。

我寫了一篇關於在Unity中使用對象生命週期管理器的article及其對處置的影響。如果您使用默認TransientLifetimeManagerPerResolveLifetimeManager,則Unity甚至不會跟蹤對象的存在,因此它不能調用Dispose。在解決的實例上調用Dispose的唯一終身管理者是ContainerControlledLifetimeManager(又名單身人士)和HierarchicalLifetimeManager。在終身管理器處置時調用Dispose

您的解決方案是使用鑄造和手動處理Dispose,或者切換到HiearchicalLifetimeManager併爲每個傳入的WCF請求創建新的子容器。每個子容器只能處理單個請求,它將處理具有分層生存期的已解決實體。

還有其他方法,例如this article圍繞Unity構建一個非常複雜的代碼來支持所有已解析對象的處理和TearDown

+1

+1。我認爲使用子容器是一個很好的解決方案。我見過那些反對它的人,因爲他們不喜歡依賴DI容器,但是我個人會認爲,如果這需要解決一個問題。 – 2011-04-20 09:22:45

+0

對於將HiearchicalLifetimeManager放到WCF的位置有什麼建議嗎?截至目前,我正在我的服務主機工廠創建我的Unity容器並從那裏進行配置。 – hoetz 2011-04-20 09:32:25

+0

那麼這取決於你如何解析對象以及你解決什麼樣的對象。例如,我實現了自定義的'IInstanceProvider'來通過構造函數注入解決整個服務及其所有依賴關係。在這種情況下,實例提供程序是您應該在子容器上創建子容器和解析服務的地方。 – 2011-04-20 09:56:56

0

答案取決於你如何與統一註冊類型/實例。拆解的標準實施完全沒有。

如果您註冊類型,然後統一不存儲參考實例它創造 - 這是由你來管理它的壽命和處置它。如果你註冊了實例,那麼實例的生命週期將被統一管理,並一直保留到你處理容器爲止。

下面的鏈接有助於瞭解有關生命週期管理好一點: http://msdn.microsoft.com/en-us/library/ff648098.aspx

你需要問自己你想配置你的對象。如果您知道何時調用ReleaseInstance,則不妨調用IDispose而不是它。

(對不起,我不熟悉WCF,所以我不確定在這方面提供的實例是什麼)