【发布时间】:2017-02-26 21:54:37
【问题描述】:
我有一个在我的 module.config.php 文件中创建非共享服务和控制器工厂的工厂。这部分配置如下所示:
"service_manager" => [
"factories" => [
Entity\User::class => Factory\Entity\UserFactory::class
],
"shared" => [
Entity\User::class => false
]
],
"controllers" => [
"factories" => [
Controller\UserAdminController::class => Factory\Controller\UserAdminControllerFactory::class
]
]
User实体是非共享的,因为我允许管理员同时添加多个用户,所以我需要实例化User实体类的多个实例。
这是我的控制器工厂:
<?php
namespace User\Factory\Controller\Core;
use User\Controller\UserAdminController;
use Interop\Container\ContainerInterface;
use User\Entity\User;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class UserAdminControllerFactory implements FactoryInterface{
/**
* @param ContainerInterface $container
* @param string $requestedName
* @param array|null $options
*
* @return UserAdminController
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null){
$serviceLocator = $container->getServiceLocator();
return new UserAdminController($serviceLocator->get(User::class));
}
/**
* @param ServiceLocatorInterface $serviceLocator
*
* @return UserAdminController
*/
public function createService(ServiceLocatorInterface $serviceLocator){
return $this($serviceLocator, UserAdminController::class);
}
}
目前,它仅在控制器的构造函数中注入 User 实体类的单个实例。但是,根据管理员想要执行的操作,我需要不确定数量的新实例。
一种可能的解决方案是每次通过在控制器中调用$this->getServiceLocator()->get(User::class) 来传递整个服务定位器并创建新实例,但这被认为是一种反模式。
这里的问题是如何在控制器中创建用户的新实例,使用 UserFactory 类?
EDIT1:添加用户工厂:
<?php
namespace User\Factory\Entity\Core;
use User\Entity\User;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class UserFactory implements FactoryInterface{
/**
* @param ContainerInterface $container
* @param string $requestedName
* @param array|null $options
*
* @return User
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null){
$urlHelper = $container->get("ViewHelperManager")->get("url");
return new User($urlHelper);
}
/**
* @param ServiceLocatorInterface $serviceLocator
*
* @return User
*/
public function createService(ServiceLocatorInterface $serviceLocator){
return $this($serviceLocator, User::class);
}
}
【问题讨论】:
-
也许你在看stackoverflow.com/questions/25447442/… 我不确定,但为什么不将工厂注入控制器并创建用户实体
-
可以分享一下UserFactory的内容吗?您是否有充分的理由为您的域实体编写工厂?无论如何,我会尝试为此类任务编写一个控制器插件。
-
@Roman 因为我的工厂需要服务定位器,如果我注入工厂,我也必须注入服务定位器,这是一种反模式。因此,我不能这样做。有什么想法吗?
-
@edigu 我不认为创建控制器插件是一个好主意,因为它会在控制器中引入更多的依赖关系并且更具体 - 在每个控制器中,因为控制器插件在应用程序范围内可用.我将添加 UserFactory,但这适用于每个具有依赖关系的对象。例如,查询数据库的表单或必须重复多次(以具有多个实例)的字段集。
-
@edigu 我已经添加了UserFactory,你可以看看。
标签: php dependency-injection zend-framework2 factory service-locator