Spring for Delphi中GlobalContainer和ServiceLocator有什么区别?

5

它们看起来很相似。我可以在GlobalContainer中注册一些内容:

GlobalContainer.RegisterType<TMyImplementation>.Implements<IMyInterface>;

可以通过GlobalContainerServiceLocator获取实例,两者都可以使用:

MyInstance := GlobalContainer.Resolve<IMyInterface>;
MyInstance := ServiceLocator.GetService<IMyInterface>;
1个回答

6

ServiceLocator用于在需要时解决代码中的依赖关系。在这种情况下,您不希望使用对容器的引用,因为这完全违反了具有松耦合代码的目的。

个人认为,服务定位器本身是一种反模式,应尽可能避免注入所有可能的东西。


ServiceLocator不是用来抽象化DI框架的吗?我使用ServiceLocator与构造函数注入相结合。 - whosrdaddy
是的。然而,在你的代码内使用它违反了“告诉别问”的原则。使用服务定位器并不比在代码中硬编码构造函数调用好多少。它将对另一个类的耦合换成了对 DI 框架的耦合。一开始由于那个硬编码的构造函数调用(无法模拟),写单元测试很困难,现在则因为你必须设置你的 di 框架或者为服务定位器编写一个模拟而变得困难。 - Stefan Glienke
我在每个类中使用2个构造函数,一个是放置依赖项(即接口)的构造函数,另一个是没有参数的构造函数,这个构造函数通过servicelocator调用另一个构造函数。因此,为了进行测试,我可以使用具有依赖项的构造函数来注入我的模拟对象。 - whosrdaddy
我知道使代码可测试的可能解决方法。我可以现在就争论为什么这是不好的,你不应该那样做,但我不会这样做。相反,我建议你阅读一些Misko Hevery关于这个主题的文章或观看演示(比如这里http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/),并得出自己的结论。另一篇很好的文章是这篇博客文章,它解释了服务定位器为什么是反模式:http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx - Stefan Glienke
1
@stefan-glienke:“ServiceLocator是用于解决您代码中依赖关系的问题”--GlobalContainerResolve方法也是如此,它们之间有什么区别?“在那里,您不想使用对容器的引用”。所以,ServiceLocator只是GlobalContainer的一个包装器,以公开较少的方法?“我同意那些认为服务定位器本身就是反模式”的人--同样的理由,GlobalContainer也是吗? - Rafael Piccolo

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