2012-06-01 67 views
4

對於諸如記錄器,安全性,配置等基礎設施項目,這些東西是否應真正注入到每個需要它們的類中,或者應該將它們注入到服務定位器中,然後這些類可以使用服務定位器來解析依賴關係或其他一些機制)?應該注入基礎設施依賴關係嗎?

它只是看起來非常荒謬,所有類有10個參數ctors來通過DI來滿足依賴關係。它的代碼味道IMO。我可以理解諸如存儲庫或服務代理/連接器之類的東西,但不能記錄日誌。

+1

您可以將它們注入到全局應用程序上下文中。並從中消費。畢竟,容器是單身單身人士。 – DarthVader

+2

氣味可能不是來自您的DI,而是來自您的10參數班,可能違反了「做一件事,做得很好」的理念。 – ken

+0

@ken這是我的觀點,DI不是一種氣味,它是10個參數。 – ILovePaperTowels

回答

2

這一切都取決於您在基礎結構和代碼的其餘部分之間畫線的位置。你認爲數據庫連接是基礎設施嗎?我不。

屬性注入是一種代碼異味,因爲它隱藏了依賴關係,並且在構造函數完成時類沒有正確初始化。只用它來解決循環依賴。

對於日誌記錄的特殊情況,我使用單例來獲取記錄器。

通常我會同意你的AOP,但我不是運行時AOP框架的粉絲,而且團隊不瞭解AOP概念。他們幾乎不瞭解IoC概念

您可能會發現我的IoC introduction有用。

4

有幾個選項。

  1. 使用屬性注入並在ctor中設置默認值。例如

    class foo 
    { 
        public ILogger Logger {get;set;} 
    
        public foo() 
        { 
         Logger = NullLogger.Instance; 
        } 
    } 
    
  2. 使用AOP類型的方法。使用動態代理可以將公共調用與日誌語句包裝在一起,但日誌記錄實際上從未實際注入組件本身。請參閱Castle.DynamicProxy或自定義.Net屬性以獲取有關此方法的更多建議。

然後就出現了這樣一個問題,爲什麼有如此多的基礎設施問題被注入組件?你所描述的被認爲是交叉切割問題,通常這是通過AOP(面向方面​​編程)的一些處理來處理的,所以核心系統中沒有很多重複。

+2

AOP +1。通常我會同意你的AOP,但我不是運行時AOP框架的粉絲,而且團隊不瞭解AOP概念。他們幾乎不瞭解IoC概念。 – ILovePaperTowels

+0

我完全理解:)你的更好的選擇,然後是#1與可選屬性注入。我受不了服務定位器。感覺就像純IoC的墊片一樣。 –

1

關於日誌記錄 - 只需使用NLog(或您最喜愛的記錄器)並完成它。除非你真的很奇怪,否則沒有理由抽象和/或注入你的記錄器。

關於配置 - 只有少數類應該是配置消費者,所以這不應該導致構造函數膨脹。有關配置和DI的良好討論,另請參閱this question

關於安全 - 同樣,我認爲只有少數類應該是安全依賴的消費者。如果很多課程都關注安全性,則可能需要重新訪問您的設計。

一般來說 - 如果一個類有太多的構造函數參數,可能是因爲它太多了,不管依賴性是否基礎設施。