【问题标题】:Accessing dependencies from within an abstract controller factory从抽象控制器工厂中访问依赖项
【发布时间】:2013-05-23 12:00:30
【问题描述】:

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

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') 工作正常,那么为什么从控制器工厂内调用不能工作?

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

【问题讨论】:

    标签: zend-framework2 abstract-factory


    【解决方案1】:

    查看错误

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

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

    <?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();
     }
    

    【讨论】:

    • 谢谢,我想可能是这样的。也将使用控制器插件方法。
    猜你喜欢
    • 2015-01-01
    • 2016-01-28
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多