2009-09-27 69 views
5

除了可測試性,利用D.I.的最大優勢是什麼? (我不是在談論一個D.I.框架或IoC)靜態類?特別是對於您知道服務不會被換出的應用程序。除了測試,依賴注入怎麼比靜態類/方法更好?

在我們的一個c#應用程序中,我們的團隊正在web web GUI,服務層和存儲庫層中使用依賴注入,而不是使用靜態方法。過去,我們會創建,修改,傳遞並由靜態類保存的POCO(業務實體對象)。

例如,在過去,我們可能已經編寫:現在

CreditEntity creditObj = CreditEntityManager.GetCredit(customerId); 
Decimal creditScore = CreditEntityManager.CalculateScore(creditObj); 
return creditScore; 

,與DI,同樣的代碼將是:

//not shown, _creditService instantiation/injection in c-tors 
CreditEntity creditObj = _creditService.GetCredit(customerId); 
Decimal creditScore = _creditService.CalculateScore(creditObj); 
return creditScore; 

沒有太大的不同,但現在我們有幾十個服務類的範圍要廣得多,這意味着我們應該把它們看作是靜態的(即沒有私有成員變量,除非它們被用來定義更多的依賴關係)。另外,如果這些方法中的任何一個使用資源(數據庫/ Web服務/等),我們會發現更難管理併發性問題,除非我們刪除依賴關係並使用舊的靜態或方法。

+5

「除了可測試性,利用D.I.的最大優勢是什麼」就像是說「除了我的頭上有一個屋頂,對於我來說,拿着工作有什麼大的優勢」。 – TrueWill 2009-09-27 15:11:00

回答

5

D.I.的問題可能是:CreditEntityManager實際上是集中關於如何找到CreditEntity以及去哪裏去CalculateScore的知識的自然地方?

我覺得D.I.的理論。是參與的事情X一個模塊化的應用程序並不一定知道如何與東西​​Ÿ即使X需求Ÿ掛鉤。

在你的例子中,你已經找到了服務提供者定位併合併到數據對象之後的代碼流。當然,無論是否有D.I.它看起來差不多,甚至可能正好相同取決於編程語言,風格等。

關鍵是如何將這些不同的服務連接在一起。在D.I.中,潛在的第三方對象本質上是做配置管理的,但在完成之後,代碼應該大致相同。 D.I.的要點不是爲了改進後來的代碼,而是爲了避免編輯邏輯上正確的模塊和程序邏輯,但是要連接錯誤的服務來試圖將問題的模塊化特性與程序的模塊化特性相匹配供應商。

+0

因此,對於沒有特別封裝的內部服務/組件(即我們絕不會將其交換出去),D.I.沒有提供很多好處? – 2009-09-27 05:32:50

+1

你仍然可能想插入模擬對象和服務進行單元測試。如果你已經有了一個測試框架,你永遠不會重新配置服務連接,或者你已經有了一個可以接受的插件體系結構,那麼當然,你可以在沒有D.I.的情況下獲勝,儘管任何類型的插件或測試框架都可能看起來像D.I.設計模式。 – DigitalRoss 2009-09-27 05:44:16

1

它允許您在不破解代碼的情況下更換實現。例如,在我的一個應用程序中,我們創建了一個名爲IDataService的接口,該接口定義了查詢數據源的方法。對於前幾個產品版本,我們使用nHibernate爲Oracle實施。後來,我們想切換到一個對象數據庫,所以我們爲db4o編寫和實現,將它的程序集添加到執行目錄並在配置文件中更改了一行。普雷斯托!我們使用db4o時無需破解代碼。

1
+0

但是,如果服務是暫時的,爲什麼要實例化一個對象?從邏輯上講,無狀態對象不會更好地由靜態類來表示嗎? – 2009-09-27 05:34:28

+0

使用DI容器時,您只需編寫服務代碼,然後爲每個服務配置適當的生活方式(這也可以是每個Web請求,每個線程或任何其他服務)。爲此,服務必須是可實例化的。如果您有疑問,請創建其他問題。 – 2009-09-27 06:01:19

+0

+1以提供確切的計數。大聲笑! – TrueWill 2009-09-27 15:03:00

0

有一個Guice video它給出了一個很好的例子使用D.I.如果你正在使用很多需要動態連接的第三方服務,我會很有幫助。