2011-01-05 20 views
11

如果已經討論過這個問題,我很抱歉,但是我沒有發現我想要的東西。我面臨的問題更多的是關於模式和設計選擇,而不是.NET本身。我只是想徵求你的建議,知道從哪裏開始我的重構。如何處理.NET中的構造函數over-injection

今天我在我的實際應用程序中打開了其中一個類,發現它有13個依賴項由構造函數注入!實際上每個開發者都會在他寫的方法中添加它所需要的依賴。

我對DI的理解的一點是,當我們通過構造函數注入一個依賴項時,這意味着它是一個強制性依賴項,應該用在類的所有方法中。如果我們只需要一個給定類的方法就需要一個特定的依賴關係,那對您意味着什麼?

  • 給定的類確實太多了?我應該考慮創建一個只需要依賴的新類型?
  • 我應該注入財產?但是在那個特定的方法中,依賴是強制性的,所以我不認爲這是一個好的選擇。
  • 我應該注射的方法?

有什麼難的是找到正確的平衡。在實際情況中,有時候不可能用乾淨的方式封裝bahaviour。

我正在考慮創建類似服務聚合器的東西,以便在其中一個相關的依賴關係後面生效,但是希望如果您有其他建議。提前致謝。

+3

相關:http://stackoverflow.com/questions/2420193/dependency-injection-constructor-madness – 2011-01-05 11:34:07

+0

這其實不是。 NET的問題,這是非常不相關的語言! – markus 2012-12-12 11:34:48

回答

25

你是正確的:如果你需要注入13依賴性成一類,那就是你違反Single Responsibility Principle一個非常明確的信號。 切換到屬性注入將不會幫助,因爲它不會減少依賴項的 - 它只會暗示這些依賴項是可選的而不是強制的。

基本上有兩種方式來處理這種類型的問題:

  • Refactor to Facade Services。這基本上是一個不中斷重構,因爲它保持了控制器的功能。然而,它將責任更改爲協調/編排服務之間的交互,而不是管理實現的細節細節。
  • 將課程拆分爲獨立的課程。如果每個服務都是由不同的開發人員引入的,以支持這些方法的一個子集,則這是低凝聚力的標誌。在這種情況下,將班級分成幾個獨立的班級會更好。

特別針對ASP.NET MVC,您可能不想分割Controller,因爲它會改變您的URL方案。這很公平,但請考慮這意味着什麼:這意味着Controller的單一職責應該是映射URL到應用程序代碼。換句話說,這就是控制器應該做的所有事情,然後才能正確解決方案重構Facade Services

10

僅僅因爲依賴是強制性的並不意味着它應該用在全部類的方法IMO中。它應該在邏輯上是類本身配置的一部分。

另一方面,如果一個類有13個依賴關係,它可能會做得太多。這些依賴關係是否在邏輯上屬於一起?也許這些依賴關係本身應該更「塊」 - 或者很可能你的班級應該少做一點。

+0

我會盡量把它分解成更小的類,但據我看到,注入的依賴關係也相互依賴。例如,一個依賴需要另一個來完成它的任務,我擔心在分解成更小的類之後,我仍然應該注入相同的依賴關係。也許不是13,但其中一些。 – 2011-01-05 11:45:01

4

這聽起來像是一個具有太多依賴性的類的情況,即它是一個上帝類。嘗試並將其分解成更多離散的職責。

+0

是的,我認爲這樣做。我面臨的另一個困難是注入的依賴關係混合在一起。在一個方法中,我需要依賴項A和D,並在下一個C和A.我認爲這個問題更重要,僅僅重構上帝類就不夠,因爲我會發現自己將相同的依賴注入到小班? – 2011-01-05 11:39:44

+2

你是唯一可以分析依賴關係的人,但是我猜想如果你打破這個類,只需要依賴關係的子集。許多開發人員添加依賴項的事實是一種非常強大的上帝級氣味,隨着時間的推移它只會變得更糟。最終你會到達臨界點,因爲宇宙中沒有足夠的時間來重構所有的上帝類。 – 2011-01-05 11:44:11

+0

我同意你的意見。 – 2011-01-05 12:34:29

0

如果你的班級有13個依賴項,你肯定有問題。很顯然你的班級承擔了太多的責任。 Marc Seemann在他的書「.NET中的依賴注入」第6.4節中討論了這個問題。如果你的類在構造函數中開始有3個參數,你必須開始懷疑。我的班級仍然負有一個責任嗎?如果你的構造函數中有4個或更多參數,那麼通過開始使用外觀或組合模式來重構你的類。

0

它只是DI的工作方式。這是事實。所以接受它。它像一個PDF服務的服務完全合法的,看看這個代碼:

public PdfService(ILocalizationService localizationService, 
     ILanguageService languageService, 
     IWorkContext workContext, 
     IOrderService orderService, 
     IPaymentService paymentService, 
     IDateTimeHelper dateTimeHelper, 
     IPriceFormatter priceFormatter, 
     ICurrencyService currencyService, 
     IMeasureService measureService, 
     IPictureService pictureService, 
     IProductService productService, 
     IProductAttributeParser productAttributeParser, 
     IStoreService storeService, 
     IStoreContext storeContext, 
     ISettingService settingContext, 
     IAddressAttributeFormatter addressAttributeFormatter, 
     CatalogSettings catalogSettings, 
     CurrencySettings currencySettings, 
     MeasureSettings measureSettings, 
     PdfSettings pdfSettings, 
     TaxSettings taxSettings, 
     AddressSettings addressSettings) 
相關問題