2009-06-27 134 views
1

我在理解如何管理我在開發的SDK中具有的內部依賴關係時遇到了一些麻煩,出於某種原因,我嘗試的所有內容似乎都很難處理。管理內部依賴關係

說我有這些類:

class Table 
{ 
    Table(string name,IQueryProvider provider, IComObject comobject) {} 
} 

class TableFactory 
{ 
    Table BuildTable(name) <- builds a table object. 
} 

是我遇到的問題是,BuildTable()方法創建一個IQueryProvider和IComObject並通過名稱下來。我已經實現了我希望什麼(如果我理解正確的話)的服務定位器模式,但如果我用這樣的:

BuildTable(string name) 
{ 
    IQueryProvider provider = ServiceLocator.GetInstance<IQueryProvider>(); 
    IComObject comobject = ServiceLocator.GetInstance<IComObject>(); 
    Table tab = new Table(name,provider,comobject); 
    return tab; 
} 

現在意味着我必須同時擁有IQueryProvider和IComObject在這使得服務定位我依賴關係難以查看和測試。所以,我創建了一個依賴工廠這樣創建不同類型的對象和工廠的東西:

class DependencyFactory 
{ 
    Table BuildTable(string name) 
    { 
     //call other BuildMethods to create objects. 
     //return new Table. 
    } 

    //Other Build methods for things like IQueryProvider, IComObject. 
} 

那麼我只有在我的服務定位器註冊DependencyFactory,然後就打電話構建方法。

有沒有這種氣味對你不好?

是我的第一個BuildTable方法好,還是我正確地關心它。

回答

0

爲了使測試更容易,您可能需要使用依賴注入來提供用於創建依賴對象的工廠。對於所有類型的對象,我都希望通過單個工廠來實現。例如,您可能有一個TableFactory for Tables。這將有兩個構造函數 - 默認的那個會導致正確的工廠被實例化,另一個構造函數允許注入依賴的對象工廠。在生產代碼中使用第一個,但在測試中使用第二個。

public class TableFactory 
{ 
     private ServiceLocator Locator { get; set; } 

     public TableFactory() : this(null) { } 

     public TableFactory(ServiceLocator locator) 
     { 
      this.Locator = locator ?? new ServiceLocator(); 
     } 

     public Table BuildTable(string name) 
     { 
      IQueryProvider provider = ServiceLocator.GetInstance<IQueryProvider>(); 
      IComObject comobject = ServiceLocator.GetInstance<IComObject>(); 
      return new Table(name,provider,comobject); 
     } 
} 

你會做類似於ServiceLocator類的事情,但是根據需要插入IQueryProvider和IComObject的實例。

請注意,這是一種非常簡單的注射類型。如果你想,你也可以通過配置文件提供依賴對象的默認版本。在這種情況下,您可能只有默認構造函數並使用屬性注入來提供依賴對象。這些屬性可能會標記爲具有內部可見性的設置器,以便您的配置類可以創建工廠並正確設置它們的屬性。然後你可以使用InternalsVisibleTo來讓測試人員可用於你的測試,並在那裏做同樣的事情。

+0

,但它仍然沒有真正解決不能夠看到的問題內部依賴關係。但是,它又是SDK的內部,所以我知道我需要什麼類型。嗯該怎麼做。 – 2009-06-27 14:07:26

0

我認爲服務定位器是一種反模式,完全是你描述的原因:它使得很難弄清楚如何正確使用類型。我建議使用依賴注入(DI);而不是Service Locator。例如(但不限於)構造器注入。您可以手動執行此操作,例如described in this blog post,或者您可以讓DI容器爲您完成工作。

通用的DI容器是:

+0

盡我所能使用DI,但我的主要問題是在哪裏以及如何創建所有要使用的對象。所以我製作工廠對象,但是我在哪裏創建這些工廠對象。 – 2009-06-27 14:38:21