2013-04-30 70 views
3

統一3提供了自動註冊(通過會議登記)新功能,如:如何防止統一覆蓋現有的映射與自動註冊

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(), //uses reflection 
    WithMappings.FromMatchingInterface, //Matches Interfaces to implementations by name 
    WithName.Default); 

此代碼將註冊實現自己的類似命名的接口上所有類型,對這些接口。例如,類爲MyService:IMyService將自動好像你已經寫了下面的註冊:

container.RegisterType<IMyService, MyService >(); 

我的問題:如果我想這大部分的時間,但我想選擇一個不同的實現我的一個接口,即使存在一個類似命名的實現?

參見:Patterns and practices on CodePlex

閱讀解釋你爲什麼會想這樣做的重要文章是傑里米·米勒的 Convention Over Configuration article

回答

1

什麼阻止你從配置加載自定義設置覆蓋自動映射(其 - 如果空 - 意味着沒有默認映射被超控):

// have your auto registration 
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(), //uses reflection 
    WithMappings.FromMatchingInterface, //Matches Interfaces to implementations by name 
    WithName.Default); 

// and override it when necessary 
container.LoadConfiguration(); 

其中配置是

<?xml version="1.0" encoding="utf-8" ?> 
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> 
<container> 
    <register type="IMyService" mapTo="OverriddenServiceImpl" /> 
</container> 
</unity> 

<?xml version="1.0" encoding="utf-8" ?> 
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> 
<container> 
     ...nothing, do not override defaults ... 
</container> 
</unity> 

移動可選配置XML文件的優點 - 你可以重新配置系統,而不需要重新編譯。

+0

這是我原來問題的最佳答案。我最終在這種方法上做了一些小改動。 – 2013-08-22 21:55:37

4

Unity一直使用「最後贏」規則進行配置。因此,先對容器進行自動配置,然後再進行覆蓋。最後的設置配置(不管發生的情況如何)將是容器中的配置。

0

我最終使用了Wiktor的方法,但略有差異,因爲我無法及時使用.NET 4.5來獲得我的解決方案。所以我無法使用自動註冊。

相反,我先裝用

container.LoadConfiguration(); 

這是認識到,在許多情況下,重要的任何XML配置,是一種抽象的默認實現,使用90%的+時間。事實上,通常情況下,除非依賴性被模擬進行測試,否則總是使用默認值。因此,使註冊默認值變得容易是個好主意。

我對我的團隊有一個約定,默認值由包含默認值的程序集中的註冊類進行註冊。註冊類可以通過反射來發現。通常,接口或抽象類將處於不同的合約程序集中。

註冊量始終包裹保護條款中:

if (!container.IsRegistered<IMyService>()) 
{ 
    container.RegisterType<IMyService, MyService>() 
} 

我還添加了一個擴展方法來IUnityContainer,使這個少一點冗長我的開發者

public static IUnityContainer RegisterIfUnRegistered<TAbstraction, TImplementation>(
     this IUnityContainer container) where TImplementation : TAbstraction 
    { 
     if (!container.IsRegistered <TAbstraction>()) 
     { 
      container.RegisterType<TAbstraction, TImplementation>(); 
     } 
     return container; //Make it fluent 
    } 

有各種重載到這一點,採取命名註冊,工廠註冊等

現在,默認的實現被發現的99%的時間,但他們可以是按照Wiktor的建議在xml中重寫。

這似乎有點太像霧裏看花。自動註冊通常會有這種感覺。它已在Castle Windsor和其他依賴容器框架中使用多年。恥辱,我們不得不等待11年才能在微軟的產品中獲得它。嗯。我離題了。

只要在實施註冊組件默認的慣例之後,就變得很容易進行單元測試和調試註冊。然而

記住,通過反射組件或通過直接調用註冊類執行註冊的代碼應該運行非常接近在可執行的主要方法。這是你的組合根。 See Mark Seeman's blog有關依賴注入的更多信息。他寫了the book on DI。我強烈推薦這個。