2011-01-08 38 views
1

我現在對DI和IoC容器有了很好的理解,但是我不確定如何處理在多個「模塊」(DLL,無論)中有幾十個類的真實世界方面。幾乎所有我見過的IoC示例都可能使用少數幾個類,並在Main方法(或Global.asax,如果是Web應用程序)中手動設置容器,這對於大型應用程序來說是瘋狂的有數百行只使用For<I>().Use<T>()語法來設置所有內容。「現實世界」中的IoC - 如何處理多個類?

我已經做了一些研究,這似乎是註冊表(StructureMap)和內核(Ninject)類的目的(這些是我熟悉的兩個IoC容器,所以在這裏提到它們 - 我相信其他IoC容器也有類似的東西)。

現在,我的問題是您是否打算創建與您的應用中的每個分組對應的不同註冊表(我一直在玩StructureMap,因此我會堅持使用該命名法)(例如存儲庫,實體,服務)讓我們假設一個「基礎設施」類庫,然後在主應用程序入口點連接這些類?我想你可以走得更遠,爲每個聚集(爲了使用DDD術語)有一個註冊表,然後將所有註冊表連接到更廣泛的註冊表類中,這些註冊表類包含整個應用程序的一部分(例如,較大的LOB應用程序的CRM部分可能本身有幾個聚集,所以你有一個註冊表接線,每個聚集,然後,結合所有的彙集登記更大的註冊表..我希望是有道理的)

對於一個簡單的例子:

// MyApp.Infrastructure 
class ServiceRegistry : Registry 
{ 
    public ServiceRegistry() 
    { 
     For<IOrderService>().Use<OrderService>(); 
     // other services... 
    } 
} 

class RepositoryRegistry: Registry 
{ 
    public RepositoryRegistry() 
    { 
     For<IOrderRepository>().Use<OrderRepository>(); 
     // other repositories... 
    } 
} 

// other registry files e.g. for Entities 

// Global.asax or Program.cs or whatever entry point 
ObjectFactory.Initialize(x => { 
    x.AddRegistry<ServiceRegistry>(); 
    x.AddRegistry<RepositoryRegistry>(); 
    // other registries 
}); 

這是處理現實世界的應用程序的首選方式,可能有幾十個,如果不是數百個類的邏輯組織?

回答

1

在StructureMap中,已經提供了註冊表聚合器。 查看scanning assemblies上的StructureMap文檔。 您應該爲每個程序集創建一個註冊表(您可以在單個程序集中執行多個註冊表,但沒有任何明顯的優勢)。

然後,您可以使用掃描功能來查找所有註冊表。您還需要使用註冊約定(在Scan()條款中),以便您不必顯式註冊每個實現。

ObjectFactory.Initialize(x => { 
    x.Scan(s => { 
    // Add the current assembly 
    s.TheCallingAssembly(); 

    // Add all assembly from a specified path 
    s.AssembliesFromPath("Extensions"); 

    // Automatically look and execute registries 
    s.LookForRegistries(); 

    // specify some conventions 
    s.WithDefaultConventions(); 
    }); 
}); 
0

當我使用Spring時,我通過圖層(web,service,persistence等)分開配置文件。像所有分層技術一樣,這些技術保留了邏輯上應該組合在一起的配置,以使關係清晰。

所有的計算機科學都有這個共同點:通過將複雜性分解成更小,更易於管理的塊來處理複雜性。

0

即使名稱註冊表可能會引起混淆,儘管它來自Fowlers企業應用程序設計模式書。您可能會考慮將入口點稱爲應用程序的組合根(請參閱Marc Seemans .NET依賴注入,來自manning的書)。 無論如何,您應該爲每個應用程序都有一個組合根,不要在應用程序之間共享組合根,因爲它們將接口與它們綁定在一起,而某些應用程序可能不需要您的所有接口。

。希望做出一些感覺:)

4

對於這樣的大型項目,你可能會想青睞約定優於配置。例如,StructureMap有一個默認的會議掃描儀,或者您可以編寫自定義掃描儀。看看這裏:http://codebetter.com/jeremymiller/2009/01/20/create-your-own-auto-registration-convention-with-structuremap/

因此,假設您通常使用構造函數注入,並且您的IoC引導程序只能看到給定程序集中接口的一個實現,您只需將其設置爲掃描該程序集,自動創建構造函數依賴關係。

0

您可能想要使用IoC的「自動裝配」功能。例如如果將接口的實現分離爲不同的程序集並且僅分發一個版本,則IoC容器將能夠自動找到合適的實現,並且不必手動告訴容器在解析時應該使用哪個實現依賴。

它在Spring.NetStructureMaps中被稱爲「自動裝配」(byType,byName,...)。