1

使用依賴注入容器時,在執行解析時檢測到缺少依賴關係。這是在運行時。使用依賴注入容器時靜態確定缺失的依賴關係

本文介紹部分解決方案。這將有助於簡化測試,調試和維護,但它仍然需要測試執行,以驗證您的行爲(特別是如果你使用運行時分辨率抽象工廠子溶液):

http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx

當使用依賴注入容器,有沒有一種方法可以靜態確定所有的依賴關係都將被解析?

回答

2

簡答:不,不能完成。

這樣做需要能夠將所有組件及其依賴關係(容器元數據)表示爲圖形,以便對其進行分析。問題是,容器越複雜,它越難實現這一點。以溫莎爲例。它的numerous extension points使依賴關係過於動態,不能用圖表來表示。懶惰的組件加載器,處理程序選擇器,工廠,組件模型貢獻者,子解析器都參與進程,它們可以是任意的用戶代碼,這使得不可能靜態分析。

靜態分析對於一個普通的容器來說可能是可行的,但是這個假設的容器對於真實世界的項目來說是相當無用的。

因此,像往常一樣,這是一種折衷方案,我們能做的最好的一些測試是對容器中所有註冊組件進行實際解析。 StructureMap有一個AssertConfigurationIsValid()方法來做到這一點。

即使如此,也可能會有更多細微的錯誤未被捕獲,如lifestyle issues

+0

最佳實踐對我來說絕對是有趣且有用的。我恰好在調查溫莎,這對我來說尤其重要。感謝有用的鏈接:) – 2010-09-03 15:59:41

5

託管擴展性框架(MEF)可以執行此操作。爲了使分析準確,您需要遵守一些最佳實踐,但結果卻不錯。

要分析一組組件,使用命令行工具 - 請參見http://blogs.msdn.com/b/nblumhardt/archive/2009/08/28/analyze-mef-assemblies-from-the-command-line.aspx。這可以從Visual Studio或持續集成服務器中的構建腳本運行 - http://blogs.msdn.com/b/nblumhardt/archive/2009/09/24/debug-composition-from-within-visual-studio.aspx

您可以直觀地做到這一點使用MefContrib項目的Visual MEFX(再次在一組組件) - 見http://xamlcoder.com/blog/2010/04/10/updated-visual-mefx/

MEF支持既是很聲明(用於配置標準屬性),並通過使用基本這個功能(它可以在不創建任何實例的情況下構建圖表......)需要一點點圍繞您的頭部。)

+0

酷!從來沒有想過這是可能的。然而,爲了公平起見,它應該在Windsor中是可能的,因爲它也將組件表示爲圖形節點,但僅限於容器的非常有限/靜態的使用情況。 – 2010-09-04 23:19:18

+0

是的 - 它更多地涉及可以被分析而不是一個全有或全無的問題。 MEF進一步做出類似於Typed Factory Facility的分析。看看Krzysztof爲Windsor v.3烹飪的內容會很有趣:) – 2010-09-05 11:47:43

1

除了Mauricio說的,Windsor 2.5還有一個功能,您可能會發現它有用診斷缺少依賴關係的問題或僅查看容器中的組件。

我寫了一篇關於它的測試版here。它現在更加有用,並且和Windsor中的所有東西一樣 - 它是可擴展的,因此您可以將自己的物品放在列表中。

alt text

0

也許不是一個依賴注入容器。但是,您可以手動執行依賴項注入,而無需使用容器。例如:

var foo = new Foo(); 
var bar = new Bar(foo); 
var program = new Program(bar); 
program.Run(); 

如果它編譯,那麼所有的依賴關係都在那裏。但是,一旦依賴關係圖增長得足夠大,以至於無法將它完全保留在頭部(特別是在混合中引發了一些循環依賴關係),麻煩就會一發不可收拾。如果重構涉及重新安排依賴關係,那麼調整構造函數調用的順序將變得很困難。

+0

雖然我很欣賞你的答案,但對我來說它並不是非常有用:)我希望我的團隊的代碼能夠分離依賴關係的構建和對依賴關係的訪問。 DI的這種使用使得它很容易忘記,或者無意中滑倒。這就是爲什麼我會主張使用DI容器和/或抽象工廠。 – 2010-09-27 22:47:07

+0

@Merlyn:我不太明白你的意思。手動依賴注入使構建階段與其餘代碼保持完全相同的方式,與容器完全相同。上面的代碼片段相當於'var program = container.Resolve ();'會做,並且會出現在代碼中的相同位置。 – 2010-09-27 23:05:48

+0

對不起,我應該糾正自己。當我說訪問時,我的意思是填充依賴性插槽。我使用這個作爲測試隔離的解決方案,所以我可以注入mock。除非我抽象傳遞給代碼的確切依賴關係,否則我會鎖定調用代碼傳遞的任何實現。我所知道的兩種解決方案是抽象工廠類(這將允許我執行您在此描述的靜態檢查)和DI容器(這是我的問題所關注的)。我已經計劃在兩種情況下都使用構造函數注入。 – 2010-09-28 18:07:52