dtrz17917 2016-08-22 07: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 12: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.

    展开全部

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

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部