2012-01-13 164 views
2

我有一組使用依賴注入實現的WCF服務用於測試目的。WCF和依賴注入

基本上這些服務有時互相調用,所以在我的單元測試中,我可以使用接口將它們作爲服務構造函數中的組件注入庫和WCF服務。

這很好,因爲我可以正確地測試這些服務,沒有任何依賴性。

爲了避免使用Visual Studio服務引用(創建大量垃圾),我也實現了自己的代理,所以我使用了ChannelFactory的CreateChannel方法。

我有點擔心現場環境會發生什麼。

會發生什麼情況是,調用另一個WCF服務的WCF服務只有一個此外部組件實例注入到構造函數中,因此我不能在使用該對象時處置該對象。

這會造成麻煩嗎? 垃圾收集器會照顧它嗎? 連接是否仍然打開? 這種方法是錯誤的嗎?

非常感謝。

回答

2

當您調用CreateChannel方法時,ChannelFactory會創建一個通道對象。該通道對象是實際上具有連接的對象。

一旦完成通道,您應該通過調用IClientChannel.Close方法關閉它。這應該會導致任何底層網絡連接關閉。請注意,在某些情況下調用Close方法可能會導致CommunicationObjectFaultedException異常,即使您首先確認您的頻道不處於Faulted狀態。

您可以在code example of this MSDN documentation page中看到在wcfClientChannel對象上調用了Close方法。

+0

感謝您的回覆,但我的問題不是如何關閉連接。我想知道如何將WCF/Web服務注入組件並正確處理服務連接。問題在於,在構造函數中將它作爲參數意味着在類級別,我只有一個它的實例,並且一旦被調用另一個方法會引發異常,就會關閉它。默認情況下,每個服務調用都是不同的實例,所以這可能只是一個哲學問題。希望它是有道理的。 – matteo75 2012-01-16 11:01:54

+0

@ matteo75我想我不清楚你的方法「外部組件」是渠道工廠還是渠道。如果渠道工廠,那麼我會更少關心處理。我認爲你的方法沒問題,但我會讓你的服務實現實現IDisposable並處理你的外部組件。在那裏設置一個突破口來驗證WCF是否應該遵守它。 – 2012-01-16 13:37:20

+0

我正在使用ChannelFactory,但此刻我還沒有實現任何服務處置。我認爲它會沒事的,但我注意到IIS越來越多地使用內存(這是在回收後發佈的),這可能是由於這種未發佈的服務連接。我不是100%確定,只是一個猜測,但瞭解在依賴注入體系結構中關閉/處置服務的最佳實踐會很好。 – matteo75 2012-01-16 15:03:59

0

是的,你應該關閉你打開的頻道。您尚未指定誰實際使用頻道工廠打開頻道。無論誰收到一個開通渠道的工廠都有責任關閉它,因爲這是唯一知道何時可以這樣做的地方。

通常,您應該打開您的頻道,撥打電話,然後立即關閉它以釋放與游泳池的連接。 ChannelFactory<T>針對此進行了優化,並將在實際中重新使用可用連接,並且只處理一次合約等。

鑑於這些觀點,我迄今最喜歡的是有另一種抽象來明確定義這些開放調用關閉語義。我稱之爲IChannelInvoker<T>,它有一個單一的Execute方法。我現在的版本是異步只,但爲了簡單起見這裏,這裏有一個同步版本會是什麼樣子:

public interface IChannelInvoker<TChannel> 
{ 
    /// <summary> 
    /// Executes a method within the context of an open channel 
    /// </summary> 
    TResult Execute<TResult>(Func<TChannel, TResult> method); 
} 

一種實現的Execute方法使用ChannelFactory打開通道,調用委託,關閉通道,並返回結果。我有工廠注入並保持應用程序的整個生命週期。

現在服務A,而不是注入通道T,你注入一個IChannelInvoker<T>。例如:

調用者也可組合,這樣你就可以添加其他IChannelInvoker<T>裝飾應用在消息層面橫切關注點,如安全性 - 添加標題等