0

我們的團隊一直在構建一個DDD應用程序,該應用程序具有構建爲系統「API」的強烈定義的應用程序服務層。它處理從領域和基礎設施一起拉取所有東西以完成通用任務。它只使用DTO作爲輸入/輸出,因此域永遠不會暴露在該層之外。我應該從UI中抽象一個IOC容器的配置嗎?

現在我們想要添加一個依賴注入容器,我們面臨一些艱難的選擇。我們有兩個使用應用程序服務完成工作的客戶端應用程序:一個MVC 2應用程序和一個Windows服務應用程序。傳統上,使依賴注入工作的所有配置代碼都放在mvc項目中的global.asax文件中,我已經看到了很多示例。問題在於國際奧委會註冊代碼然後在Windows服務中被複制,併爲該平臺稍作修改。

我的問題是,DI需要客戶端應用程序知道要註冊什麼以及如何,這還需要客戶端應用程序引用域和基礎結構層。具有應用程序服務層的整個想法是,這是客戶應該知道和談論的唯一事情。我建議的解決方案是在我的應用程序服務層創建一個「依賴服務」,客戶端只需調用一次,它會配置DI容器,因爲它知道需要什麼。它也有方法允許客戶端應用程序註冊其自己的附加依賴項。例如,MVC項目將註冊其控制器工廠,並且Windows服務將註冊其啓動類。我想知道這是否不常見,或者如果我在這個想法上走錯了路。有沒有其他人遇到過這個問題?

回答

2

我把一個配置類放到我的DDD或DomainModel項目中,並在UI中調用配置類。

public static class IoCConfigurator() 
{ 
    public static void Initialize() 
    { 
     // your code here 
    } 
} 

在您的用戶界面中,您只需調用Initialize()方法即可。你可以在你的MVC Global.asax中使用它,甚至可以在你的Windows服務應用程序中使用它。沒有代碼重複。

適用於我。

+0

如何註冊網絡特定類型,例如,這種方式? IoCConfigurator是否需要知道並被綁定到所有不同的可能執行環境?如果您需要在Web主機下的容器中註冊MVC控制器,您可能也不想將它們註冊(或者甚至部署程序集)到服務進程主機。 – 2010-12-07 22:36:13

+0

這取決於我的項目涉及哪個部分。如果我在我的DomainModel項目中需要IoC,那麼我將在此項目中爲此特殊依賴項創建一個IoCConfigurator。如果我在我的WebUI MVC項目中也需要IoC,我也會爲這個項目創建一個IoCConfigurator。我儘量讓項目儘可能鬆散。例如,當我需要WebService項目中的DomainModel程序集時,我不會手動處理IoC配置。我假設在這個程序集中有特定依賴關係的配置器。 – Mariusz 2010-12-08 08:04:23

3

有很多方法來給貓皮;看起來你正在採取錯誤的做法。應用程序的入口點(Global.asax或Program.cs)絕對應該是選擇要在IoC容器中配置的組件的位置。另一方面,您的服務通常不應該嵌入任何IoC配置知識。我的猜測是你已經遵循了這個原則,但是由於重複的配置而正在重新檢查它。如上所述,爲了使這種方法可行,無需代碼重複,許多IoC容器提供了模塊化結構,這些模塊化結構封裝了一組相關組件的組態。在Autofac(和Ninject IIRC)中,這些被稱爲'模塊' - http://code.google.com/p/autofac/wiki/StructuringWithModules。溫莎城堡稱他們爲「安裝者」,而StructureMap稱他們爲「登記處」。

通過將配置分解爲模塊,可以減少應用程序啓動方法中配置代碼的數量。在你的榜樣,作爲一個簡化,您可以創建三個模塊:

  • CoreModule
  • WebModule
  • ServiceProcessModule

的CoreModule將包含配置爲共享的組件和行爲相同每個執行環境。

WebModule和ServiceProcessModule將包含特定於這些環境的組件的註冊,以及根據主機配置不同的任何共享組件的專門配置。然後

你的web應用程序的啓動會是這樣的:

foo.RegisterModule<CoreModule>(); 
foo.RegisterModule<WebModule>(); 
// Resolve root component, run app 

雖然服務過程會非常相似,但對於ServiceProcessModule代WebModule。

與具有條件代碼的靜態初始化方法相比,此類型的配置對於許多應用程序入口點和/或組件的許多子系統來說可以更好地擴展。

希望這會有所幫助。 尼克

相關問題