2013-04-30 65 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。我强烈推荐这个。