aimfeld / zend-di-compiler
一个使用自动生成的工厂代码进行依赖注入的Zend Framework 2模块。
Requires
- php: >=7.0
- laminas/laminas-config: >=2.6
- laminas/laminas-di: >=2.6
- laminas/laminas-servicemanager: ^3.0
Replaces
- aimfeld/di-wrapper: *
This package is auto-updated.
Last update: 2020-11-26 10:56:31 UTC
README
注意:此仓库不再积极维护。自laminas-di版本3开始,其变化很大,现在对即时(aot)工厂代码生成有更好的支持,因此建议直接使用laminas-di。
目录
简介
你在Zend Framework 2应用中是否厌倦了为Laminas\ServiceManager编写大量的工厂代码(闭包)?过时的工厂方法是否导致错误?使用ZendDiCompiler可以避免这些问题!
ZendDiCompiler是一个使用自动生成的工厂代码进行依赖注入的Zend Framework 2模块。它为你节省了大量工作,因为现在无需再编写Laminas\ServiceManager的工厂闭包并手动更新它们。
ZendDiCompiler使用Laminas\Di扫描你的代码并自动创建工厂方法。如果工厂方法过时,ZendDiCompiler将在后台更新它们。因此,你可以更快地开发,避免由于过时的工厂方法导致的错误,并在生产中获得更好的性能!
特性
- 用于创建DI定义的代码扫描和自动工厂代码生成。
- 可以处理<强>共享实例强>和<强>类型偏好强>。
- 允许使用自定义代码自省策略(默认情况下,仅扫描构造函数)。
- 可以作为Laminas\ServiceManager的补充使用。
- 检测过时的生成工厂代码和自动重新扫描(非常适合开发)。
- 可以创建新实例或重用之前创建的实例。
- 可以作为运行时对象的工厂使用,结合DI和传递运行时参数。
- 与使用带有缓定义的Laminas\Di\Di相比,具有<强>更高的性能强>和更少的内存消耗。
注意事项
- 尚未支持设置器注入和接口注入。实例必须通过构造器注入(我仍然推荐使用这两种方法之一)进行注入。
- 如果你正在开发大型应用或框架,使用ZendDiCompiler是有意义的。对于小型应用,ZendDiCompiler可能有些过度,你应该使用Laminas\ServiceManager回调方法来处理实例化。
安装
此模块在 Packagist 上可用。在您的项目的 composer.json
中使用
{
"require": {
"aimfeld/zend-di-compiler": "1.*"
}
}
对于 PHP 7,请安装 2.x 版本,对于 PHP 5.4-5.6,请使用 1.x 版本。
确保您在应用程序根目录中有一个可写的 data 文件夹,请参阅 ZendSkeletonApplication。在其中放置一个包含以下内容的 .gitignore
文件
*
!.gitignore
将 'ZendDiCompiler'
添加到您的 application.config.php
中的模块数组中。ZendDiCompiler 必须在它所使用的模块之后加载
'modules' => array( 'SomeModule', 'Application', 'ZendDiCompiler', ),
使用方法
依赖注入容器与服务定位器
ZendDiCompiler 是一个 依赖注入容器 (DiC) 还是 服务定位器 (SL)?这取决于您在哪里使用它。ZendDiCompiler 可以用作 DiC 来 在模块类中创建您的控制器 并从外部注入控制器依赖项。纯 DiC 使用意味着 ZendDiCompiler 仅在引导过程中使用,并在控制器分发之前释放。这被称为 "Register Resolve Release 模式",并由 Mark Seemann 等专家推荐。
一旦您将 ZendDiCompiler 注入到您的控制器和其他类中,您就将其用作 服务定位器。ZF2 MVC 架构基于具有操作方法的控制器类。鉴于这种架构,控制器依赖项会迅速增加。为了避免控制器构造函数膨胀,将 ZendDiCompiler 作为单个依赖项注入到 ZF2 控制器类中,并使用它从控制器内部拉取其他依赖项是有意义的。这意味着像使用 Laminas\ServiceManager
一样使用它作为 服务定位器。
ZendDiCompiler 还在提供的 ZendDiCompiler\DiFactory
中用作 服务定位器,这对于 创建具有依赖项的运行时对象 非常有用。这避免了您必须编写的许多 抽象工厂代码。除了 ZF2 控制器之外,我建议不要在任何地方直接注入 ZendDiCompiler。如果您需要您的一个类中的服务,只需在构造函数中请求它即可。如果您需要创建具有依赖项的运行时对象,注入 DiFactory 或其扩展版本,并使用 自定义创建方法。
配置
ZendDiCompiler 使用标准的 Laminas\Di 配置(目前尚未很好地记录)。为了简化,请参阅 example.config.php 以获取如何指定的示例
- 代码扫描器目录
- 实例配置
- 类型偏好
有关配置选项的完整列表,请参阅 module.config.php
ZendDiCompiler在data
目录下创建一个GeneratedServiceLocator
类,并在开发过程中构造函数发生变化时自动刷新它。然而,如果您例如更改了实例配置中的参数,您必须手动删除data/GeneratedServiceLocator.php
来强制刷新。在您的预发布和生产部署/更新过程中,确保删除data/GeneratedServiceLocator.php
!
共享实例
在以下情况下,您需要在您的应用程序模块的onBootstrap()方法中为ZendDiCompiler::addSharedInstances()
提供共享实例(也请参阅以下示例)
- 要注入的对象是扫描目录之外的一个类的实例。
- 要注入的对象需要一些特殊的引导(例如,一个会话对象)。
请注意,ZendDiCompiler会自动提供一些默认共享实例(请参阅ZendDiCompiler::getDefaultSharedInstances())。以下默认共享实例可以在不显式添加的情况下进行构造函数注入
ZendDiCompiler\ZendDiCompiler
ZendDiCompiler\DiFactory
Laminas\Mvc\MvcEvent
Laminas\Config\Config
Laminas\View\Renderer\PhpRenderer
Laminas\Mvc\ApplicationInterface
Laminas\ServiceManager\ServiceLocatorInterface
Laminas\EventManager\EventManagerInterface
Laminas\Mvc\Router\RouteStackInterface
类型偏好
通常需要注入接口或抽象类。让我们看看接口注入(对于抽象类,工作方式相同)。
class ServiceF { public function __construct(ExampleInterface $example) { // ExampleImplementor is injected since it is a type preference for ExampleInterface $this->example = $example; } }
我们需要告诉ZendDiCompiler为ExampleInterface
注入哪个实现类。在我们的示例配置中,将ExampleImplementor
指定为ExampleInterface
的类型偏好
'di' => array( 'instance' => array( 'preference' => array( 'ZendDiCompiler\Example\ExampleInterface' => 'ZendDiCompiler\Example\ExampleImplementor', ), ), ),
现在,ZendDiCompiler将始终为ExampleInterface
注入ExampleImplementor
。调用ZendDiCompiler::get('ZendDiCompiler\Example\ExampleInterface')
将返回ExampleImplementor
。
类型偏好不仅可以用于接口和抽象类,还可以用于一般类替代。它们甚至可以用于处理不存在的类
'di' => array( 'instance' => array( 'preference' => array( 'ZendDiCompiler\Example\NotExists' => 'ZendDiCompiler\Example\Exists', ), ), ),
调用ZendDiCompiler::get('ZendDiCompiler\Example\NotExists')
将返回一个ZendDiCompiler\Example\Exists
实例。信或不信,实际上有一些很好的用例。
示例
此处列出的所有示例源代码都包含在源代码中。
使用ZendDiCompiler创建控制器
假设我们想使用ZendDiCompiler创建一个控制器类并注入一些依赖项。为了说明,我们还注入了ZendDiCompiler本身到控制器中。如上所述,这是否有用是一个值得讨论的话题。但是,如果我们决定在控制器内部使用ZendDiCompiler来获取其他依赖项,我们可以在构造函数中注入它或从ZF2服务定位器中拉取它使用$this->serviceLocator->get('ZendDiCompiler')
。
在我们的示例中,我们有以下类
ExampleController
use Laminas\Mvc\Controller\AbstractActionController; use ZendDiCompiler\ZendDiCompiler; use Laminas\Config\Config; class ExampleController extends AbstractActionController { public function __construct(ZendDiCompiler $zendDiCompiler, ServiceA $serviceA, ServiceC $serviceC, Config $config) { $this->zendDiCompiler = $zendDiCompiler; $this->serviceA = $serviceA; $this->serviceC = $serviceC; $this->config = $config; } }
ServiceA,依赖于ServiceB
class ServiceA { public function __construct(ServiceB $serviceB) { $this->serviceB = $serviceB; } }
ServiceB,构造函数参数类型未指定
class ServiceB { public function __construct($diParam) { $this->diParam = $diParam; } }
ServiceC 需要进行复杂的运行时初始化,并将作为共享实例添加。
class ServiceC { public function init(MvcEvent $mvcEvent) { $sm = $mvcEvent->getApplication()->getServiceManager(); $router = $mvcEvent->getRouter(); // Some complicated bootstrapping using e.g. the service manager and the router } }
我们将示例源目录添加为 ZendDiCompiler 的扫描目录。由于 ServiceB
有一个未指定类型的参数,我们必须指定一个要注入的值。对于 ServiceB
来说,更好的方法是在其构造函数中要求 Config
,并从中检索参数,这样我们就不需要指定实例配置了。我们示例的 配置 看起来是这样的
// ZendDiCompiler configuration 'zendDiCompiler' => array( // Directories that will be code-scanned 'scanDirectories' => array( // e.g. 'vendor/provider/module/src', __DIR__ . '/../src/ZendDiCompiler/Example', ), ), // ZF2 DI definition and instance configuration used by ZendDiCompiler 'di' => array( // Instance configuration 'instance' => array( // Type preferences for abstract classes and interfaces. 'preference' => array( 'ZendDiCompiler\Example\ExampleInterface' => 'ZendDiCompiler\Example\ExampleImplementor', ), // Add instance configuration if there are specific parameters to be used for instance creation. 'ZendDiCompiler\Example\ServiceB' => array('parameters' => array( 'diParam' => 'Hello', )), ), ),
现在我们可以在应用程序的 模块类 中创建 ExampleController
。为了方便,我们从服务管理器中检索 ZendDiCompiler 并将其分配给一个局部变量($this->zendDiCompiler = $sm->get('ZendDiCompiler')
)。这使得编写 getControllerConfig()
或 getViewHelperConfig()
回调变得更加容易。
由于 ServiceC
依赖关系需要一些复杂的初始化,我们需要对其进行初始化并将其添加为共享实例到 ZendDiCompiler。
class Module { protected $zendDiCompiler; public function getControllerConfig() { return array( 'factories' => array( // Suppose one of our routes specifies a controller named 'ExampleController' 'ExampleController' => function() { return $this->zendDiCompiler->get('ZendDiCompiler\Example\ExampleController'); }, ), ); } public function onBootstrap(MvcEvent $mvcEvent) { $sm = $mvcEvent->getApplication()->getServiceManager(); // Provide ZendDiCompiler as a local variable for convience $this->zendDiCompiler = $sm->get('ZendDiCompiler'); // Set up shared instance $serviceC = new ServiceC; $serviceC->init($mvcEvent); // Provide shared instance $this->zendDiCompiler->addSharedInstances(array( 'ZendDiCompiler\Example\ServiceC' => $serviceC, )); } }
使用 DiFactory 创建具有依赖关系的运行时对象
区分两种类型的对象是有用的:服务 和 运行时对象。对于 服务,所有参数都应在配置中指定(例如,一个包装在 Laminas\Config\Config
对象中的配置数组)。如果类构造函数(例如第三方代码)需要一些自定义参数,它们可以在 实例配置 中指定)。
另一方面,运行时对象 需要至少一个仅在运行时确定的参数。ZendDiCompiler 提供了 ZendDiCompiler\DiFactory
来帮助您创建 运行时对象 并注入它们的依赖关系。
在一个数组中传递所有运行时参数
如果您遵循以单个名为 $zdcParams
的数组传递运行时参数的约定,如 RuntimeA
中所示,那么事情非常简单(数组名称可以在 module.config.php 中配置)
class RuntimeA { public function __construct(Config $config, ServiceA $serviceA, array $zdcParams = array()) { $this->config = $config; $this->serviceA = $serviceA; $this->params = $zdcParams; } }
ZendDiCompiler 自动将 ZendDiCompiler\DiFactory
注入为 默认共享实例。因此,我们只需在 ServiceD
中使用它来创建 RuntimeA
对象。RuntimeA
的依赖关系(Config
默认共享实例和 ServiceA
)将自动注入,因此您只需要提供运行时参数。
use ZendDiCompiler\DiFactory; class ServiceD { public function __construct(DiFactory $diFactory) { $this->diFactory = $diFactory; } public function serviceMethod() { $runtimeA1 = $this->diFactory->create('ZendDiCompiler\Example\RuntimeA', array('hello', 'world')); $runtimeA2 = $this->diFactory->create('ZendDiCompiler\Example\RuntimeA', array('goodbye', 'world')); } }
传递自定义运行时参数
如果您无法或不想遵循在单个 $zdcParams
数组中传递所有运行时参数的约定,ZendDiCompiler 仍然非常有用。在这种情况下,您可以直接从 ZendDiCompiler\DiFactory
扩展一个自定义工厂并添加您特定的创建方法。RuntimeB
需要两个单独的运行时参数
class RuntimeB { public function __construct(Config $config, ServiceA $serviceA, $runtimeParam1, $runtimeParam2) { $this->config = $config; $this->serviceA = $serviceA; $this->runtimeParam1 = $runtimeParam1; $this->runtimeParam2 = $runtimeParam2; } }
因此,我们从 ExampleDiFactory
扩展 ZendDiCompiler\DiFactory
并编写一个创建方法 createRuntimeB
class ExampleDiFactory extends DiFactory { /** * @param string $runtimeParam1 * @param int $runtimeParam2 * @return RuntimeB */ public function createRuntimeB($runtimeParam1, $runtimeParam2) { $config = $this->zendDiCompiler->get('Laminas\Config\Config'); $serviceA = $this->zendDiCompiler->get('ZendDiCompiler\Example\ServiceA'); return new RuntimeB($config, $serviceA, $runtimeParam1, $runtimeParam2); } }
在 ServiceE
中,我们注入了我们的扩展工厂。如果扩展工厂位于由 ZendDiCompiler 扫描的目录中,我们不需要将其作为共享实例提供。现在我们可以创建如下所示的 RuntimeB
对象
class ServiceE { public function __construct(ExampleDiFactory $diFactory) { $this->diFactory = $diFactory; } public function serviceMethod() { $runtimeB1 = $this->diFactory->createRuntimeB('one', 1); $runtimeB2 = $this->diFactory->createRuntimeB('two', 2); } }
生成的代码和信息
工厂代码
ZendDiCompiler 将自动在 data/ZendDiCompiler
目录中生成服务定位器,并在开发期间如果构造函数发生变化时更新它。可以使用 ZendDiCompiler::get()
创建/检索服务。如果您需要在某个类中添加新的依赖项,只需将其放入构造函数中,ZendDiCompiler 将为您注入它。
仅作说明,这是由 ZendDiCompiler 创建并在 ZendDiCompiler::get()
中使用的生成服务定位器。
namespace ZendDiCompiler; use Laminas\Di\ServiceLocator; /** * Generated by ZendDiCompiler\Generator (2013-03-07 21:11:39) */ class GeneratedServiceLocator extends ServiceLocator { /** * @param string $name * @param array $params * @param bool $newInstance * @return mixed */ public function get($name, array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services[$name])) { return $this->services[$name]; } switch ($name) { case 'ZendDiCompiler\Example\ExampleController': return $this->getZendDiCompilerExampleExampleController($params, $newInstance); case 'ZendDiCompiler\Example\ExampleDiFactory': return $this->getZendDiCompilerExampleExampleDiFactory($params, $newInstance); case 'ZendDiCompiler\Example\ExampleImplementor': return $this->getZendDiCompilerExampleExampleImplementor($params, $newInstance); case 'ZendDiCompiler\Example\Module': return $this->getZendDiCompilerExampleModule($params, $newInstance); case 'ZendDiCompiler\Example\RuntimeA': return $this->getZendDiCompilerExampleRuntimeA($params, $newInstance); case 'ZendDiCompiler\Example\ServiceA': return $this->getZendDiCompilerExampleServiceA($params, $newInstance); case 'ZendDiCompiler\Example\ServiceB': return $this->getZendDiCompilerExampleServiceB($params, $newInstance); case 'ZendDiCompiler\Example\ServiceC': return $this->getZendDiCompilerExampleServiceC($params, $newInstance); case 'ZendDiCompiler\Example\ServiceD': return $this->getZendDiCompilerExampleServiceD($params, $newInstance); case 'ZendDiCompiler\Example\ServiceE': return $this->getZendDiCompilerExampleServiceE($params, $newInstance); case 'ZendDiCompiler\Example\ServiceF': return $this->getZendDiCompilerExampleServiceF($params, $newInstance); default: return parent::get($name, $params); } } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ExampleController */ public function getZendDiCompilerExampleExampleController(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ExampleController'])) { return $this->services['ZendDiCompiler\Example\ExampleController']; } $object = new \ZendDiCompiler\Example\ExampleController($this->get('ZendDiCompiler\ZendDiCompiler'), $this->getZendDiCompilerExampleServiceA(), $this->getZendDiCompilerExampleServiceC(), $this->get('Laminas\Config\Config')); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ExampleController'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ExampleDiFactory */ public function getZendDiCompilerExampleExampleDiFactory(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ExampleDiFactory'])) { return $this->services['ZendDiCompiler\Example\ExampleDiFactory']; } $object = new \ZendDiCompiler\Example\ExampleDiFactory($this->get('ZendDiCompiler\ZendDiCompiler')); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ExampleDiFactory'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ExampleImplementor */ public function getZendDiCompilerExampleExampleImplementor(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ExampleImplementor'])) { return $this->services['ZendDiCompiler\Example\ExampleImplementor']; } $object = new \ZendDiCompiler\Example\ExampleImplementor(); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ExampleImplementor'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\Module */ public function getZendDiCompilerExampleModule(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\Module'])) { return $this->services['ZendDiCompiler\Example\Module']; } $object = new \ZendDiCompiler\Example\Module(); if (!$newInstance) { $this->services['ZendDiCompiler\Example\Module'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\RuntimeA */ public function getZendDiCompilerExampleRuntimeA(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\RuntimeA'])) { return $this->services['ZendDiCompiler\Example\RuntimeA']; } $object = new \ZendDiCompiler\Example\RuntimeA($this->get('Laminas\Config\Config'), $this->getZendDiCompilerExampleServiceA(), $params); if (!$newInstance) { $this->services['ZendDiCompiler\Example\RuntimeA'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ServiceA */ public function getZendDiCompilerExampleServiceA(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ServiceA'])) { return $this->services['ZendDiCompiler\Example\ServiceA']; } $object = new \ZendDiCompiler\Example\ServiceA($this->getZendDiCompilerExampleServiceB()); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ServiceA'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ServiceB */ public function getZendDiCompilerExampleServiceB(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ServiceB'])) { return $this->services['ZendDiCompiler\Example\ServiceB']; } $object = new \ZendDiCompiler\Example\ServiceB('Hello'); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ServiceB'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ServiceC */ public function getZendDiCompilerExampleServiceC(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ServiceC'])) { return $this->services['ZendDiCompiler\Example\ServiceC']; } $object = new \ZendDiCompiler\Example\ServiceC(); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ServiceC'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ServiceD */ public function getZendDiCompilerExampleServiceD(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ServiceD'])) { return $this->services['ZendDiCompiler\Example\ServiceD']; } $object = new \ZendDiCompiler\Example\ServiceD($this->get('ZendDiCompiler\DiFactory')); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ServiceD'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ServiceE */ public function getZendDiCompilerExampleServiceE(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ServiceE'])) { return $this->services['ZendDiCompiler\Example\ServiceE']; } $object = new \ZendDiCompiler\Example\ServiceE($this->getZendDiCompilerExampleExampleDiFactory()); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ServiceE'] = $object; } return $object; } /** * @param array $params * @param bool $newInstance * @return \ZendDiCompiler\Example\ServiceF */ public function getZendDiCompilerExampleServiceF(array $params = array(), $newInstance = false) { if (!$newInstance && isset($this->services['ZendDiCompiler\Example\ServiceF'])) { return $this->services['ZendDiCompiler\Example\ServiceF']; } $object = new \ZendDiCompiler\Example\ServiceF($this->getZendDiCompilerExampleExampleImplementor()); if (!$newInstance) { $this->services['ZendDiCompiler\Example\ServiceF'] = $object; } return $object; } }
代码扫描日志
ZendDiCompiler 将在 data/ZendDiCompiler/code-scan.log
中记录代码扫描期间发现的问题。如果您无法从 ZendDiCompiler 中检索对象,您可能在该日志中找到原因。最常见的问题是您在构造函数中使用了未类型化的标量参数而不是 参数数组,并且没有在您的 Laminas\Di 配置 中提供值。以下是一个显示一些问题的代码扫描日志示例
INFO (6): Start generating service locator by code scanning.
DEBUG (7): Survey\Cache\Zf1CacheAdapter: Class Laminas\Cache\Storage\StorageInterface could not be located in provided definitions.
DEBUG (7): Survey\DataAggregator\Aggregate: Missing instance/object for parameter data for Survey\DataAggregator\Aggregate::__construct
DEBUG (7): Survey\Db\Table\Rowset: Missing instance/object for parameter config for Survey\Db\Table\Rowset::__construct
DEBUG (7): Survey\DbValidate\ValidationResult: Missing instance/object for parameter errorCount for Survey\DbValidate\ValidationResult::__construct
DEBUG (7): Survey\Form\MessageContainer: Missing instance/object for parameter intro for Survey\Form\MessageContainer::__construct
DEBUG (7): Survey\Input\ValidationResult: Missing instance/object for parameter level for Survey\Input\ValidationResult::__construct
DEBUG (7): Survey\Mail\Mailer\MailerResult: Missing instance/object for parameter success for Survey\Mail\Mailer\MailerResult::__construct
DEBUG (7): Survey\Paginator\Adapter\DbSelect: Class Zend_Db_Select could not be located in provided definitions.
DEBUG (7): Survey\Pdf\Prince: Missing instance/object for parameter exePath for Survey\Pdf\Prince::__construct
DEBUG (7): Survey\SkipLogic\ConditionResult: Missing instance/object for parameter isTrue for Survey\SkipLogic\ConditionResult::__construct
DEBUG (7): Survey\System\SystemInfo: Missing instance/object for parameter lastEventFlowUpdate for Survey\System\SystemInfo::__construct
DEBUG (7): Survey\TokenLinker\ActionResult: Missing instance/object for parameter action for Survey\TokenLinker\ActionResult::__construct
DEBUG (7): Survey\UserSurveyManager\UpdateStatusesResult: Missing instance/object for parameter updatesCount for Survey\UserSurveyManager\UpdateStatusesResult::__construct
INFO (6): Code scanning finished.
INFO (6): Writing generated service locator to ./data/ZendDiCompiler/GeneratedServiceLocator.php.
INFO (6): Finished writing generated service locator to ./data/ZendDiCompiler/GeneratedServiceLocator.php.
对于没有任何服务依赖项的简单 值对象,我不使用依赖注入,而是使用 new
创建它们,例如 ConditionResult::__construct($isTrue, $isCacheable, $allowFlip = true)
。这些对象不打算用 DiFactory 创建,因此可以忽略 DEBUG
通知。
组件依赖信息
作为额外的好处,ZendDiCompiler 将写入一个 component-dependency-info.txt
文件,其中包含有关哪些扫描组件依赖于哪些类的信息。
扫描的类被分组到组件中(例如,Laminas\Mvc\MvcEvent 类属于 Laminas\Mvc 组件)。对于每个组件,都会列出所有构造函数注入的类。这有助于您分析哪些组件依赖于其他组件的哪些类。考虑将您的组件组织成层。每个层应仅依赖于同一层或更低层的类。请注意,仅考虑构造函数注入进行此分析,因此图片可能不完整。
以下是一个您可能会看到的示例
...
MyLibrary\Mail classes inject:
- MyLibrary\Mail\Transport
- MyLibrary\TextEngine\TextEngine
- Laminas\Config\Config
MyLibrary\Validator classes inject:
- MyLibrary\Db\Tables
- MyLibrary\I18n\Translator\Translator
...