猿问
下载APP

依赖注入和服务定位器模式之间有什么区别?

依赖注入和服务定位器模式之间有什么区别?

这两种模式看起来都像是控制反转原理的实现。也就是说,一个对象不应该知道如何构造它的依赖关系。

依赖注入(DI)似乎使用构造函数或setter来“注入”它的依赖项。

使用构造函数注入的示例:

//Foo Needs an IBarpublic class Foo{
  private IBar bar;
  public Foo(IBar bar)
  {
    this.bar = bar;
  }
  //...}

服务定位器似乎使用了一个“容器”,它连接了它的依赖关系并给它foo吧。

使用服务定位器的示例:

//Foo Needs an IBarpublic class Foo{
  private IBar bar;
  public Foo()
  {
    this.bar = Container.Get<IBar>();
  }
  //...}

因为我们的依赖项只是对象本身,所以这些依赖项具有依赖项,它们具有更多依赖项,依此类推。因此,控制容器的反转(或DI容器)诞生了。示例:Castle Windsor,Ninject,Structure Map,Spring等)

但是,IOC / DI容器看起来完全相同像一个服务定位器。将它称为DI容器是一个坏名字?IOC / DI容器只是另一种服务定位器吗?当我们有很多依赖关系时,我们使用DI容器这一事实的细微差别是什么?


精慕HU
浏览 66回答 3
3回答

30秒到达战场

差异可能看起来很小,但即使使用ServiceLocator,该类仍然负责创建其依赖项。它只是使用服务定位器来完成它。使用DI,该类被赋予其依赖性。它既不知道,也不关心它们来自何处。这样做的一个重要结果是DI示例更容易进行单元测试 - 因为您可以将其依赖对象的模拟实现传递给它。如果需要,您可以将两者结合起来 - 并注入服务定位器(或工厂)。

牧羊人nacy

使用服务定位器时,每个类都将依赖于服务定位器。依赖注入不是这种情况。依赖注入器通常在启动时仅调用一次,以将依赖注入到某个主类中。这个主类依赖的类将递归地注入它们的依赖项,直到你有一个完整的对象图。一个很好的比较:http://martinfowler.com/articles/injection.html如果您的依赖注入器看起来像服务定位器,类直接调用注入器,它可能不是依赖注入器,而是服务定位器。

45度呼吸

服务定位器隐藏依赖关系 - 当从对象获取连接时,您无法通过查看对象是否访问数据库(例如)。使用依赖项注入(至少构造函数注入),依赖项是显式的。此外,服务定位器打破了封装,因为它们提供了对其他对象的依赖关系的全局访问点。使用服务定位器,与任何单例一样:很难为客户端对象的接口指定前置和后置条件,因为其实现的工作可以从外部进行干预。使用依赖项注入,一旦指定了对象的依赖项,它们就会受到对象本身的控制。
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答