使用服务定位器反模式和使用Castle Windsor容器有什么区别?

7

最近,我一直试图理解使用服务定位器“反模式”和使用Castle Windsor容器之间的区别。我在互联网上找到了一些信息,并在一篇未完成的博客文章中总结了我迄今为止学到的东西。

修改:到目前为止,我一直认为依赖注入是确保分离的唯一需要的东西。但无论我看哪里,都会推向像Castle Windsor这样的容器。我想清楚地理解原因。 请…给我讲得简单明白一点 :)


你用什么软件制作的图表? - devdigital
1
yUML: http://yuml.me/ - Francesco Gallarotti
2
我在这里尝试回答了那个问题:http://blog.ploeh.dk/2011/08/25/ServiceLocatorrolesvs.mechanics - Mark Seemann
虽然目前为止两个答案都是正确的,但我希望能把赏金给@MarkSeemann,因为正是由于他,我终于理解了组合根的概念,因此也明白了DI容器和服务定位器之间的区别。Mark,你能否添加一个回答来解释一下我在博客文章结尾所添加的内容呢?谢谢!!! - Francesco Gallarotti
3个回答

19
有趣的是你要求我用六岁小孩能理解的方式来解释这个问题;以下是一个五岁小孩能看懂的解释 :)
无论我看到哪里,都在推动像Castle Windsor之类的容器的方向。实际上,我认为这样做的原因是大多数人实际上并不理解什么是依赖注入,这意味着他们找到了一个替代他们已经习惯使用的 “new”关键字的方法,而没有理解控制反转的概念。然后他们找到了一个DI容器,并将其(误)用作服务定位器。不幸的是,这很容易做到。
这就是为什么在我的书中,我解释了所有DI的概念,而没有将解释与任何单个DI容器耦合在一起。这实际上是本书的主要内容。
服务定位器和依赖注入是实现松散耦合的两个根本不同的尝试。服务定位器有许多缺点,而且没有提供DI没有提供的任何优势。这就是为什么我认为将服务定位器称为反模式是安全的原因。
你不需要一个DI容器来使用DI;实际上,我会说,除非采取相当复杂的方法,否则最好避免使用它

@MichaelKohne 抱歉,现在已经修复了。 - Mark Seemann

3

一个服务定位器可能只是某个控制反转容器(例如Castle Windsor)的包装器。关键在于你的代码(理想情况下)应该只在你的组合根处引用容器。

因为控制反转容器支持依赖链,当你从容器中解析出根类型时,所有它的依赖项以及任何后代依赖项都将被注入。

如果你希望在运行时创建更多类型,则可以使用工厂,这些工厂也可以引用你的容器,如果你希望利用容器和接口的映射来获取依赖链的优势。


3
当您使用服务定位器时,您的代码会随处调用定位器以获取服务。当您使用控制反转时,只有一个地方(组合根)可以调用容器。应用程序的其余部分不应该知道容器的存在。

当你说“容器感知”时,是否指的是“无感知”? - Charleh
UPS“不应该具备容器感知能力” :) - Aleš Roubíček

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接