0

我正在阅读关于 Service Manager 的 Zend 3 文档,我遇到了这个问题。

在文档中它说如果我们的控制器中有一些 DI,我们应该更新module.config.php文件并添加控制器键并调用控制器而不是InvokableFactory::class使用自定义工厂类并添加另一个键 service_manager 包含我的第一个控制器使用的类数组。

好的,我这样做:

模块.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 原生的\Zend\Db\TableGateway\TableGatewayInterface,我现在必须再次编辑我的 conf 文件并添加TableGatewayInterface.

这是错误的。我永远不应该被迫以这种方式注入原生 zend 类和服务。

那我做错了什么?

4

1 回答 1

1

如果您的 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 ;
}

此 ZF3 教程页面和以下内容中对此进行了描述。

于 2016-08-25T20:56:41.037 回答