Zend framework2 Zend Di vs ServiceManager依赖项注入容器

Zend framework2 Zend Di vs ServiceManager依赖项注入容器,zend-framework2,zend-servicemanager,Zend Framework2,Zend Servicemanager,当我们有ServiceManager时,DI用于什么,它的用例是什么 它们看起来很相似,因为在zend di和zend servicemanager的配置文件中,我们可以设置一些选项,例如别名和可调用项 我正试图更好地了解这些组件背后发生的事情,而文档并没有给我足够的信息 您能告诉我区别是什么吗?什么时候我应该使用Di而不是ServiceManager Zend\DI依赖于魔术(如反射)来检测和注入依赖项,而service manager使用用户提供的工厂。这是主要区别 由于复杂性、调试和性能问

当我们有
ServiceManager
时,
DI
用于什么,它的用例是什么

它们看起来很相似,因为在
zend di
zend servicemanager
的配置文件中,我们可以设置一些选项,例如
别名
可调用项

我正试图更好地了解这些组件背后发生的事情,而文档并没有给我足够的信息


您能告诉我区别是什么吗?什么时候我应该使用
Di
而不是
ServiceManager

Zend\DI依赖于魔术(如反射)来检测和注入依赖项,而service manager使用用户提供的工厂。这是主要区别

由于复杂性、调试和性能问题,社区中有点不赞成使用Di,而支持SM。 它应该对RAD有好处,但您需要高于平均水平的知识才能正确使用它


另一方面,SM有非常详细和明确的连接,您可以在一年后打开代码,轻松地找出发生了什么

Zend\Di
负责将类连接在一起,而使用
Zend\ServiceManager
您必须手动连接,并为要实例化的每个类编写工厂闭包

Zend\ServiceManager
速度快得多,因为它不依赖速度慢的服务器。另一方面,为具有数百个类的大型应用程序编写闭包变得非常乏味。随着应用程序的增长,使闭包保持最新将变得更加棘手

为了解决这个问题,我编写了一个Zend Framework 2模块,名为。它依赖于
Zend\Di
扫描代码并自动生成工厂代码来实例化类。您可以充分利用这两个组件:
Zend\Di
的强大功能和
Zend\ServiceManager
的性能


我在的文档中做了大量工作,还提供了一些简单且更高级的使用示例。

基本上区别如下:

  • Zend\ZerviceManager
    =工厂驱动的IoC容器
  • Zend\Di
    =自动布线IoC实现
Zend\Di
已针对版本3进行重构。它的行为现在比v2更加可靠和可预测,它被设计成无缝集成到zend servicemanager中,以提供自动布线功能(不再有奇怪的魔力)。因为它使用PHP的反射api来解决依赖关系,所以比工厂驱动的方法慢。因此,版本3附带了一个AoT编译器来创建一个预解析的注入器,该注入器省略了反射的使用。另外一个好处是:生成的工厂也可以直接与
Zend\ServiceManager
一起使用


有一个关于将AoT与这两个组件一起使用的指南:

这是一个很好的答案,我记得很早就使用了DI,我不会再使用它了。这是否意味着我可能会拒绝使用DI,sm也会做这项工作?正如Xerkus指出的那样。Di内容几乎被认为是无润滑的,Di容器只是过于复杂。ServiceManager以更加用户友好的方式解决了相同的核心问题。@user1650441通常建议使用service manager
Zend\Di
很好,但我没有可以从中获益的任务,如果我需要做一些复杂的东西的原型设计,我可能会。Xerkus,我会稍微更新你的答案,以备将来阅读。Di不是魔法和纯粹的反射
Zend\Di
是一个功能强大的组件,但也相当复杂。您可以调整Di以使其与服务管理器一样快,但是您需要将定义编译成类似于服务管理器工厂的东西。Di是可插入的,此时反射是定义的唯一“读取器”。还计划了其他“阅读器”,但由于复杂性,编写了一个服务管理器组件。这是如此的受欢迎,以至于整个代码库都转向了SM。关于容器的一个很好的讨论通常是基于现代建议的“不要自己使用DI或SM”,除非它们已经是框架的一部分。Zend使用基于工厂的服务管理器(本质上是一个受限的DI容器),您必须注意不要将任何容器注入到您自己的任何类中,但您可以将容器用作应用程序设置的一部分。i、 e.在Zend中,您可以使用框架本身的功能来定制依赖关系的连接方式。最近的一些例子如下: