zend框架2:如何正确地将工厂注入到控制器中以获得不同的映射器类?

时间:2016-05-05 13:21:40

标签: php zend-framework2 apigility

我正在使用基于ZF2构建的Apigility。一旦请求被分派到控制器的动作,我需要选择适当的适配器来处理请求 - 基于接收参数。

通常,Controller由ControllerFactory实例化,您可以在其中提供所有依赖项,假设我需要som类型的mapper类进行注入。如果我知道,我会在控制器中使用哪一个很容易。如果我需要让控制器决定使用哪个映射器,那就有问题了。

假设用户正在通过参数getStatus请求'adapter1'之类的内容,而其他用户正在访问相同的操作,但使用参数'adapter2'

所以,我需要注入adapter1映射器或adapter2映射器,它具有类似的接口,但构造函数不同。

如何处理这种情况的正确方法是什么?

可能的解决方案是提供某种工厂方法,它将提供所请求的适配器,但是 - 应该避免使用SM int模型类。

另一种方法是在Controller的操作中直接使用SM,但这不是最佳方法,因为我不能将“switch-case”逻辑重用于其他操作/控制器。

请问如何处理?

1 个答案:

答案 0 :(得分:0)

你可以使用控制器插件。

就像那样,您可以在需要时在控制器内部获得适配器,而无需注入ServiceManager并且无需将所有逻辑添加到工厂。只有在控制器操作方法中请求适配器时,才会实例化适配器。

首先,您需要创建控制器插件类(扩展Zend\Mvc\Controller\Plugin\AbstractPlugin):

<?php
namespace Application\Controller\Plugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class AdapterPlugin extends AbstractPlugin{

    protected $adapterProviderService;

    public function __constuct(AdapterProviderService $adapterProviderService){
        $this->adapterProviderService = $adapterProviderService;
    }

    public function getAdapter($param){
        // get the adapter using the param passed from controller

    }
}

然后是工厂在课堂上注入你的服务:

<?php
namespace Application\Controller\Plugin\Factory;

use Application\Controller\Plugin\AdapterPlugin;

class AdapterPluginFactory implements FactoryInterface
{
    /**
     * @param  ServiceLocatorInterface $serviceController
     * @return AdapterPlugin
     */
    public function createService(ServiceLocatorInterface $serviceController)
    {
        $serviceManager = $serviceController->getServiceLocator();
        $adapterProvicerService = $serviceManager>get('Application\Service\AdapterProviderService');
        return new AdapterPlugin($adapterProviderService);
    }
}

然后您需要在module.config.php

中注册您的插件
<?php
return array(
    //...
    'controller_plugins' => array(
        'factories' => array(
            'AdapterPlugin' => 'Application\Controller\Plugin\Factory\AdapterPluginFactory',
        )
    ),
    // ...
);

现在您可以在控制器操作中使用它,如下所示:

protected function controllerAction(){
    $plugin = $this->plugin('AdapterPlugin');
    // Get the param for getting the correct adapter
    $param = $this->getParamForAdapter();
    // now you can get the adapter using the plugin
    $plugin->getAdapter($param);
}

详细了解控制器插件here in the documentation