Zend3中服务管理器的正确使用方法
Correct way to use service manager in Zend3
我在阅读有关服务管理器的 Zend 3 文档时遇到了这个问题。
在文档中说,如果我们的控制器中有一些 DI,我们应该更新 module.config.php
文件并添加控制器键并调用控制器,而不是使用 InvokableFactory::class
而使用自定义工厂 class并添加另一个键 service_manager,其中包含我的第一个控制器使用的 classes 数组。
好的,我这样做:
module.config.php
'service_manager' => [
'factories' => [
Controller\Controller2::class => Factory\Controller2Factory::class,
Controller\Controller3::class => Factory\Controller3Factory::class,
],
],
'controllers' => [
'factories' => [
Controller\Controller1::class => Factory\Controller1Factory::class
],
]
Controller1Factory.php
class Controller1Factory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new Controller1(
$container->get(Controller2::class),
$container->get(Controller3::class),
);
}
}
但是现在我有一个错误,Controller2 和 Controller3 在它们的构造函数中也有 DI,所以我创建了新的自定义工厂等等……直到我得到我的模型。
模型也有注入到它们的控制器中的依赖项,它是 zend native \Zend\Db\TableGateway\TableGatewayInterface
,我现在必须再次编辑我的 conf 文件并添加 TableGatewayInterface
。
这是错误的。我永远不应该被迫以这种方式注入原生 zend classes 和服务。
所以我做错了什么?
如果您的 Controller 没有依赖项,最好像您一样在 module.config.php
中声明它。
但是如果它有依赖关系,最好在Module.php
中进行。您首先声明您的服务,然后是控制器(不要忘记从 module.config.php
中删除它),在其中注入它所依赖的服务:
public function getServiceConfig()
{
return [
'factories' => [
Model\MyObjectTable::class => function($container) {
$tableGateway = $container->get(Model\MyObjectTableGateway::class);
return new Model\MyObjectTable($tableGateway);
},
Model\MyObjectTableGateway::class => function($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\User());
return new TableGateway('myObject', $dbAdapter, null, $resultSetPrototype);
},
]
];
}
public function getControllerConfig()
{
return [
'factories' => [
Controller\MyObjectController::class => function($container) {
return new Controller\MyObjectController(
$container->get(Model\MyObjectTable::class)
);
},
]
];
}
在你的控制器中:
private $table;
public function __construct(MyObjectTable $table)
{
$this->table = $table ;
}
我在阅读有关服务管理器的 Zend 3 文档时遇到了这个问题。
在文档中说,如果我们的控制器中有一些 DI,我们应该更新 module.config.php
文件并添加控制器键并调用控制器,而不是使用 InvokableFactory::class
而使用自定义工厂 class并添加另一个键 service_manager,其中包含我的第一个控制器使用的 classes 数组。
好的,我这样做:
module.config.php
'service_manager' => [
'factories' => [
Controller\Controller2::class => Factory\Controller2Factory::class,
Controller\Controller3::class => Factory\Controller3Factory::class,
],
],
'controllers' => [
'factories' => [
Controller\Controller1::class => Factory\Controller1Factory::class
],
]
Controller1Factory.php
class Controller1Factory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new Controller1(
$container->get(Controller2::class),
$container->get(Controller3::class),
);
}
}
但是现在我有一个错误,Controller2 和 Controller3 在它们的构造函数中也有 DI,所以我创建了新的自定义工厂等等……直到我得到我的模型。
模型也有注入到它们的控制器中的依赖项,它是 zend native \Zend\Db\TableGateway\TableGatewayInterface
,我现在必须再次编辑我的 conf 文件并添加 TableGatewayInterface
。
这是错误的。我永远不应该被迫以这种方式注入原生 zend classes 和服务。
所以我做错了什么?
如果您的 Controller 没有依赖项,最好像您一样在 module.config.php
中声明它。
但是如果它有依赖关系,最好在Module.php
中进行。您首先声明您的服务,然后是控制器(不要忘记从 module.config.php
中删除它),在其中注入它所依赖的服务:
public function getServiceConfig()
{
return [
'factories' => [
Model\MyObjectTable::class => function($container) {
$tableGateway = $container->get(Model\MyObjectTableGateway::class);
return new Model\MyObjectTable($tableGateway);
},
Model\MyObjectTableGateway::class => function($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\User());
return new TableGateway('myObject', $dbAdapter, null, $resultSetPrototype);
},
]
];
}
public function getControllerConfig()
{
return [
'factories' => [
Controller\MyObjectController::class => function($container) {
return new Controller\MyObjectController(
$container->get(Model\MyObjectTable::class)
);
},
]
];
}
在你的控制器中:
private $table;
public function __construct(MyObjectTable $table)
{
$this->table = $table ;
}