注册表模式 Vs 服务定位器模式 Vs 依赖注入容器

Posted

技术标签:

【中文标题】注册表模式 Vs 服务定位器模式 Vs 依赖注入容器【英文标题】:Registry pattern Vs Service locator pattern Vs Dependency Injection Container 【发布时间】:2015-03-07 09:42:08 【问题描述】:

它们之间有什么区别而不是通过键设置和获取数组中的对象吗?

class Registry

  private $container=array();
  public static function Set($name,$object)
    self::$container[$name]=$object;
  
  public static function &Get($name)
    return self::$container[$name];
  

【问题讨论】:

【参考方案1】:

注册表模式

Registry pattern 是一种模式,用于查找仅知道其名称的对象。此模式在内部存储对象的实例,并使用字典映射稍后检索这些实例。

DI 容器/DI 模式

DI 容器包含一个注册表,该注册表具有 object typesabstractions 的映射。更先进的是,当一个对象被解析时,它被实例化,对象的所有依赖项也是如此。

当您从 DI 容器请求对象时,您会得到一个 对象图,以您请求的对象作为根开始。每个依赖对象都是通过递归遍历每个类的构造函数来自动注入的,从没有依赖关系的类开始,并使用注册表作为指导来实例化每个对象。

依赖注入是doesn't necessarily use a DI container 的模式。 DI 模式由位于应用程序入口点的composition root 组成。组合根是注册类型和实例化根对象图的地方。一旦根对象被实例化,应用程序就会自行运行。应用程序本身没有对 DI 容器的引用,也没有与它紧密耦合。

服务定位器

很多人认为服务定位器是anti-pattern。这个想法是您要么将容器注入到您的对象中,要么使用对 DI 容器的静态引用在运行时创建实例。

主要区别在于应用程序显式依赖(因此紧密耦合到)DI容器。

使用 Service Locator 的另一个缺点是,由于您正在注入 DI 容器,因此无法从类构造函数中看到它依赖于哪些接口。相反,您必须查阅文档或分析源代码以确定类的依赖项。

尽管被认为是反模式,但在某些情况下仍然可以使用它。但是,在所有其他选项(环境上下文、属性注入等)都已用尽之后,它应该被视为最后的手段。

【讨论】:

所以,注册中心可以作为一个简单的服务定位器。 @xmedeko - 不完全是。注册表模式无法控制实例的生命周期,但将 DI 容器注入应用程序可让 DI 容器显式控制实例的生命周期。后者可以为每种类型赋予不同的生命周期,前者始终是单例生命周期,无论请求的类型如何。

以上是关于注册表模式 Vs 服务定位器模式 Vs 依赖注入容器的主要内容,如果未能解决你的问题,请参考以下文章

依赖注入和服务定位器模式有啥区别?

使用哪种模式进行日志记录?依赖注入还是服务定位器?

使用 Ninject、MVC 3 和使用服务定位器模式的依赖注入

AngularJS(15)-依赖注入

AngularJS 依赖注入

AngularJS依赖注入