我的应用程序中的大多数控制器都需要能够访问当前登录用户的“帐户”,所以我试图将其注入每个控制器类。这样做的方法似乎是为控制器类创建一个抽象工厂,它可以提供所有依赖项。所以我用一个方法创建了工厂类:
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无法获取或创建帐户实例
在控制器操作中调用$this->getServiceLocator()->get('Account')
工作正常,为什么这个调用不能在控制器工厂内工作?
或者有更好的方法来实现这个目标吗?
答案 0 :(得分:2)
查看错误
Zend \ Mvc \ Controller \ ControllerManager :: get无法获取或创建帐户实例
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()
文件中的框架并将闭包定义为工厂以构建插件,并将服务注入其构造函数> p>
<?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();
}