2010-02-17 102 views
10

我個人喜歡從C#代碼中配置StructureMap的選項。根據我的理解,DI的優勢之一是我們可以輕鬆地交換一個新的具體實例。但是,如果配置是在代碼中定義的,那麼具體實例將在dll中進行硬編碼。Xml配置或通過代碼配置?

所以,實際上,它和硬編碼的依賴關係一樣好,對吧?我知道,在測試過程中,它使生活更輕鬆...

我的觀點是,不是更好地使用XML配置呢?你想插入一個新的具體實例?只需讓你的安裝程序用新的覆蓋整個結構圖。配置文件。

那麼,配置StructureMap的首選方法是什麼?

附加:我不得不暫時使用C#配置,因爲我不知道如何將連接字符串傳遞給實例。我可以在配置文件中編寫連接字符串,但是我想重用在app.config中定義的連接字符串。

回答

17

無論您使用哪個特定的DI容器,都應該總是將應用程序的對象圖的分辨率推遲到last responsible moment。這稱爲應用程序的Composition Root

您可以編寫大量的應用程序without ever referencing the DI Container。這也意味着您可以在代碼或配置之間進行配置之間的決定,直到您需要它。

shouldn't need the container at all for unit testing,但可能需要它進行集成測試。但是,在集成測試中,您可能需要與最終應用程序不同的容器配置。

總而言之,在代碼中配置容器是目前的首選方法,因爲它更健壯,您可以應用基於約定的配置機制。

XML配置往往更加脆弱和過於冗長。在大多數情況下,它只會減慢你的速度,因爲你沒有重構或編譯器支持。

但是,如果您需要能夠交換依賴關係而無需重新編譯應用程序,則XML配置仍然有效。大多數DI容器可以讓你混合使用這些方法,這樣你就可以在代碼中完成大部分配置,但是爲了擴展性的原因,在XML中定義了一些選定的依賴關係。

+0

嗯......這聽起來是合理的。謝謝!! –

+0

雖然我同意你的答案。看來這個問題真的被問到如何讓我的應用程序配置進入我的類型。 – KevM

+0

@KevM,不是真的。我的問題是關於哪個配置選項更好。它出現了,因爲我無法使用xml將我的連接字符串輸入到我的類型中。我將不得不在connectionmap.config文件中再次寫入連接字符串。我本來想避免在兩個地方維護連接字符串。 –

6

要回答您的問題,您可以在StructureMap中找到您的蛋糕並將其吃掉。您可以使用代碼配置您的容器,並從應用程序配置中獲取所需的額外配置。這就是EqualToAppSetting的用途。

創建一個設置類

public class DatabaseSettings 
{ 
    public DatabaseSettings(string type, string connectionString) 
    { 
     Type = type; 
     ConnectionString = connectionString; 
    } 

    public string Type { get; set; } 
    public string ConnectionString { get; set; } 
} 

下一頁告訴StructureMap使用你的應用程序設置進行配置。

 [Test] 
    public void setup_concrete_class_via_application_configuration() 
    { 
     var container = new Container(config => 
     { 
      config.ForConcreteType<DatabaseSettings>().Configure 
       .Ctor<string>("type").EqualToAppSetting("dovetail.database.type", "mssql") 
       .Ctor<string>("connectionString").EqualToAppSetting("dovetail.database.connectionString"); 

     }); 

     var databaseSettings = container.GetInstance<DatabaseSettings>(); 
     databaseSettings.Type.ShouldEqual("mssql"); 
     databaseSettings.ConnectionString.ShouldEqual("Data Source=.; Initial Catalog=dovetail;User Id=sa;Password=sa;"); 
    } 

最後這裏是應用程序設置看起來像我的應用程序配置什麼:

<appSettings> 
    <add key="dovetail.database.type" value="mssql"/> 
    <add key="dovetail.database.connectionString" value="Data Source=.;Initial Catalog=dovetail;User Id=sa;Password=sa;"/>  
</appSettings> 
+0

我的確在想這個,但是我的缺點是我不得不跟蹤兩個地方的連接字符串。一個在這裏,一次在web/app.config的connectionstring部分...感謝您的回覆:) –

+0

上午使用您的建議,目前解決我的連接字符串問題。在應用程序開始時,我編輯web.config以包含一個名爲connectionString的新應用程序設置。它從正確的connectionStrings節中定義的connectionString中獲取它的值。因此我只能在一個地方修改連接字符串。並且我的結構圖配置可以從appsettings中讀取它......謝謝! –

+0

樂意提供幫助。我們烘焙了一種傳統方式將配置拉入設置對象的方式,以避免任何容器配置。我應該真的寫博客。 – KevM