【发布时间】:2009-10-13 01:15:19
【问题描述】:
这两种模式似乎都是控制反转原则的实现。也就是说,一个对象不应该知道如何构造它的依赖关系。
依赖注入 (DI) 似乎使用构造函数或设置器来“注入”它的依赖项。
使用构造函数注入的例子:
//Foo Needs an IBar
public class Foo
{
private IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
//...
}
Service Locator 似乎使用了一个“容器”,它连接了它的依赖关系并为 foo 提供了它的 bar。
使用服务定位器的示例:
//Foo Needs an IBar
public class Foo
{
private IBar bar;
public Foo()
{
this.bar = Container.Get<IBar>();
}
//...
}
因为我们的依赖关系只是对象本身,所以这些依赖关系有依赖关系,它们有更多的依赖关系,依此类推。于是,Inversion of Control Container(或DI Container)诞生了。示例:Castle Windsor、Ninject、Structure Map、Spring 等)
但 IOC/DI 容器看起来完全类似于服务定位器。称它为 DI 容器是一个坏名字吗? IOC/DI 容器只是服务定位器的另一种类型吗?当我们有许多依赖项时,我们主要使用 DI 容器这一事实是否存在细微差别?
【问题讨论】:
-
控制反转意味着“一个对象不应该知道如何构造它的依赖关系”?!?那个对我来说是新的。不,真的,这不是“控制反转”的意思。请参阅 martinfowler.com/bliki/InversionOfControl.html 那篇文章甚至提供了该术语的词源参考,可以追溯到 1980 年代。
-
Mark Seemann 认为服务定位器是反模式 (blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern)。此外,我发现图表(在此处找到,stackoverflow.com/a/9503612/1977871)有助于理解 DI 和 SL 困境。希望这会有所帮助。
标签: design-patterns dependency-injection service-locator