dtrz17917 2016-08-22 15:11
浏览 16
已采纳

在Zend 3中使用服务管理器的正确方法

I was reading Zend 3 documentation on Service Manager and i got this problem.

In documentation it says that if we have some DI in our controller we should update module.config.php file and add controllers key and invoke controller not with InvokableFactory::class but with custom factory class and add another key service_manager that contains array of classes that my first controller uses.

Ok so i do that:

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),
        );
    }
}

But now i have error that Controller2 and Controller3 also have DI in their constuctors, so i make new custom factories and so on and so on...until i get to my models.

And Models also have Dependency that is injected in their controller which is zend native \Zend\Db\TableGateway\TableGatewayInterface and i now have to edit my conf file again and add TableGatewayInterface.

And that is wrong. I should never be forced to inject native zend classes and services this way.

So what am i doing wrong?

  • 写回答

1条回答 默认 最新

  • douzi2778 2016-08-25 20:56
    关注

    If your Controller has no dependency, it's the best way to declare it in module.config.php as you did.

    But if it has dependecies, it's better to do it in Module.php. You first declare your services, then the controller (don't forget to remove it from module.config.php), injecting in it the services it depends :

    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)
                    );
                },
            ]
        ];
    }
    

    And in your controller:

    private $table;
    
    public function __construct(MyObjectTable $table)
    {
        $this->table = $table ;
    }
    

    It is described in This ZF3 tutorial page and following.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥30 用arduino开发esp32控制ps2手柄一直报错
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿