2010-02-19 49 views
4

有時我需要獲取某些構造信息的類。我不是在談論到其他對象(其將被注入),但有關(例如)的字符串,其持有唯一的參考信息:DI容器:如何將配置傳遞給對象

// Scoped as singleton! 
class Repository 
{ 
    public Repository(InjectedObject injectedObject, string path) { ... } 
} 

你如何得到這個字符串注入?一個方法可行是編寫Init()方法並避免噴射的字符串:

class Repository 
{ 
    public Repository(InjectedObject injectedObject) { ... } 
    public void Init(string path) { ... } 
} 

另一個可能性是所述信息包裝成一個對象,其中可被注入:

class InjectedRepositoryPath 
{ 
    public InjectedRepositoryPath(string path) { ... } 
    public string Path { get; private set; } 
} 

class Repository 
{ 
    public Repository(InjectedObject injectedObject, InjectedRepositoryPath path) { ... } 
} 

這樣我d在我的DI容器的初始化期間必須創建一個InjectedRepositoryPath的實例並註冊這個實例。但是我需要爲每個類似的類提供這樣一個獨特的配置對象。

我當然可以解決RepositryFactory代替Repository對象,因此工廠會問我要的路徑:

class RepositoryFactory 
{ 
    Repository Create(string path) { ... } 
} 

但同樣,這是一個工廠只爲一個單獨的對象...
或者,最後,由於路徑將會從配置文件中提取,我可以跳過字符串周圍的傳球和我的構造函數讀取配置(這可能不是最優的,但有可能):

class Repository 
{ 
    public Repository(InjectedObject injectedObject) 
    { 
     // Read the path from app's config 
    } 
} 

你最喜歡的方法是什麼?對於非單身人士課程,您必須使用imho Init()或工廠解決方案,但單身人士範圍的對象又如何?

回答

2

我更喜歡沒有DI容器指定我的API設計。容器應該符合正確的設計,而不是相反。

DI-friendly的方式設計您的課程,但不會對您的DI容器做出讓步。如果您需要連接字符串,請通過構造函數獲取字符串:

public class Repository : IRepository 
{ 
    public Repository(string path) { //... } 
} 

許多DI容器可以處理原始值。作爲一個例子,這裏有溫莎做到這一點的一種方法:

container.Register(Component.For<IRepository>() 
    .ImplementedBy<Repository>() 
    .DependsOn(new { path = "myPath" })); 

但是,如果你選擇的容器不能與原始參數處理,你總是可以裝點Repository與知道如何查找的字符串的實現:

public class ConfiguredRepository : IRepository 
{ 
    private readonly Repository decoratedRepository; 

    public ConfiguredRepository() 
    { 
     string path = // get the path from config, or whereever appropriate 
     this.decoratedRepository = new Repository(path); 
    } 

    // Implement the rest of IRepository by 
    // delegating to this.decoratedRepository 
} 

現在你可以簡單地告訴你的容器映射IRepositoryConfiguredRepository,同時仍保持核心庫推行清潔。

+0

非常有趣的鏈接,謝謝你的答案! – tanascius 2010-02-22 16:20:20

3

如果你正在使用構造函數注入,我發現添加一個參數是你的配置對象的構造函數是最好的方法。通過使用一個init函數,你有點回避構造函數注入的問題。這使得測試更加困難,這也使得維護和交付更加困難。

發現成爲一個問題,因爲這個類不需要配置對象。通過將其添加到構造函數中,任何使用此對象的人都明確知道此配置必須存在。

+0

我也有同樣的感覺。 – Kangkan 2010-02-19 16:38:53

相關問題