2016-06-13 52 views
1

这部分是尚未回答的同一问题的重复。看到这里:How can I override a component registered in Castle Windsor?覆盖温莎城堡的组件注册?哪个容器支持它?

因为我不能评论或张贴任何现有问题的答案我再次创建这个问题,希望有人知道一个看似基本和简单的问题的答案。

记住:

  1. 我不希望创建一个新的容器。
  2. 我不在乎容器是否不应该用于单元测试。
  3. 我不想使用派生容器。

如果温莎城堡不能提供这个简单的功能,你会推荐什么其他的容器实现?

+0

我相信你的问题来自你的两个“局限” - #1和#2。如果确实是* unit *测试,那么一个容器就会按照你的方式进行 - 你有一块*代码在测试*,你的依赖应该都被嘲笑。如果您是*集成*测试,那么使用容器可能是有意义的。但在这种情况下,*您应该使用与您的应用程序不同的容器*并嘲笑与测试无关的任何内容。 [重用容器](http://blog.ploeh.dk/2015/01/06/composition-root-reuse/)有点像为一个不同的应用程序重用'.config'文件 - 为什么你会这样? – NightOwl888

+1

@ NightOwl888:这是用于集成测试。新的容器没有意义,例如我想测试一切,除了log4net组件。或者除了数据库访问层之外的一切。 如果我创建一个新的容器,我不测试真正的主题,但其他的东西不是重点。容器映射代码的复制/粘贴也不是最佳实践(经常见到)。 –

+0

[我如何覆盖Castle Windsor中注册的组件?](http://stackoverflow.com/questions/1687574/how-can-i-override-a-component-registered-in-castle-windsor) –

回答

0

回答问题的第二部分 - 哪些容器支持注册覆盖。

Ninject

请参阅绑定()/取消绑定()方法。

我也试过Autofac,但看起来注册在被构建后变成冻结。所以似乎Autofac可能也不可能。

1

我不知道其他容器,但卡斯特,所以我的答案是关于城堡。如果你想替换你能做的就是写一个扩展方法给IWindsorContainer,它将删除然后添加。

但我认为你应该重新考虑了一下你的设计:

  1. 为什么你的类需要容器的直接访问,并尝试通过自己从中化解?
  2. 为什么需要更改测试代码的源代码?如果根据SOLID编写干净的依赖注入代码,您的测试将真正“神奇地”流动。

您能否介绍一下关于设计和相关课程的更多内容?

1

温莎与“最后登记获胜”的会议合作。但是,如果你没有明确告诉它,这个组件将被覆盖,它会抛出一个异常。因此,有3种方法可以允许覆盖现有组件:

  1. 使用.IsDefault()注册组件。这将覆盖现有的注册。
  2. 使用.IsFallback()注册组件。这将允许组件在稍后覆盖 。
  3. 使用组件的唯一名称 - .named(“NewComponentName”)。

我个人比较喜欢。IsDefault()并在我的集成测试中使用这种简写扩展:

public static class WindsorContainerExtensions 
    {    
     public static void Override<TService>(this IWindsorContainer container, TService instance) where TService : class 
     { 
      container.Register(Component.For<TService>().Instance(instance).IsDefault()); 
     } 
    } 
+0

IsFallback和IsDefault看起来像是一种解决方案。关于它的坏处是你需要改变被测试的主题,那就是你需要以特定的方式注册你的组件,以便以后测试它们。最终我使用了Ninject和绑定/取消绑定功能。温莎似乎缺乏基本的功能,所以我不得不做出这个决定。 –

+0

您不需要更改正在测试的主题。 .IsDefault()用于单元测试,当你不想更换组件时。 – andree