0

我的应用程序中的大多数控制器都需要能够访问当前登录用户的“帐户”,因此我试图将其注入每个控制器类。这样做的方法似乎是为可以提供所有依赖项的控制器类创建一个抽象工厂。所以我用一个方法创建了工厂类:

public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
    $controllerClassName = $requestedName.'Controller';

    $controller = new $controllerClassName();

    $account = $serviceLocator->get('Account');
    $controller->setAccount($account);

    return $controller;
}

但是该$serviceLocator->get('Account');行给了我错误:

Zend\Mvc\Controller\ControllerManager::get 无法获取或创建 Account 实例

从控制器操作中调用$this->getServiceLocator()->get('Account')工作正常,那么为什么这个调用不能从控制器工厂内工作呢?

或者有更好的方法来实现这一点吗?

4

1 回答 1

2

看看错误

Zend\Mvc\Controller\ControllerManager::get 无法获取或创建 Account 实例

ControllerManager没有名为 的服务,Account它只有控制器。您需要从控制器管理器中获取主服务定位器

$account = $serviceLocator->getServiceLocator()->get('Account');

或者有更好的方法来实现这一点吗?

就个人而言,我发现更好的方法是使用控制器插件作为代理来包装服务

首先使用接受您的服务实例作为其参数的构造函数创建插件

<?php
namespace Application\Controller\Plugin;

use Zend\Mvc\Contoller\Plugin\AbstractPlugin;

class Account extends AbstractPlugin
{
    protected $account;

    public function __construct($account)
    {
         $this->account = $account;
    }

    // .. write plugin methods to proxy to your service methods 

    public function getId()
    {
        return $this->account->getId();
    }
}

然后通过Module.php使用该getControllerPluginConfig()方法将其注册到文件中的框架并将其定义为工厂来组成插件,并将您的服务注入其构造函数,从而使其可用

<?php
namespace Application;
class Module
{
    public function getControllerPluginConfig()
    {
        return array(
            'factories' => array(
                 'account' => function($sm) {
                      $account = $sm->getServiceLocator()->get('Account')
                      // create a new instance of your plugin, injecting the service it uses
                      $plugin = new \Application\Controller\Plugin\Account($account);
                      return $plugin;
                 },
             ),
        );
    }
}

最后,在您的控制器(任何控制器)中,您可以调用插件方法来访问您的服务

 public function actionIndex()
 {
     $accountId = $this->account()->getId();
 }
于 2013-05-23T12:19:59.103 回答