1

내 module.config.php 파일에 비공개 서비스 및 컨트롤러 팩토리를 만드는 팩토리가 있습니다. 구성의이 부분은 다음과 같습니다 : 나는 관리자가 동시에 여러 사용자를 추가 할 수 있기 때문에ZendFramework2에 ServiceLocator를 삽입하지 않고 여러 비공유 인스턴스를 만드는 방법은 무엇입니까?

"service_manager" => [ 
    "factories" => [ 
     Entity\User::class => Factory\Entity\UserFactory::class 
    ], 
    "shared" => [ 
     Entity\User::class => false 
    ] 
], 
"controllers" => [ 
    "factories" => [ 
     Controller\UserAdminController::class => Factory\Controller\UserAdminControllerFactory::class 
    ] 
] 

이용자 엔티티가 아닌 공유하다, 그러므로 나는 사용자 엔티티 클래스의 여러 인스턴스를 인스턴스화 할 필요가 .

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

} 

현재는 컨트롤러의 생성자 내부의 사용자 엔티티 클래스의 단일 인스턴스를 주입 :

여기 내 컨트롤러 공장입니다. 그러나 관리자가 수행하려는 작업에 따라 정의되지 않은 양의 새 인스턴스가 필요합니다.

가능한 해결책 중 하나는 전체 서비스 탐지기를 전달하고 컨트롤러에서 $this->getServiceLocator()->get(User::class)을 호출하여 매번 새로운 인스턴스를 만드는 것입니다. 그러나 이것은 안티 패턴으로 간주됩니다.

여기에있는 질문은 UserFactory 클래스를 사용하여 컨트롤러에서 사용자의 새 인스턴스를 만드는 방법입니까?

EDIT1 : UserFactory 추가 :

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

} 
+0

어쩌면 여기에 당신이 무엇을보고 있습니다 http://stackoverflow.com/questions/25447442/dependency-injection-in-factories?rq=1 확실하지 않지만 컨트롤러에 팩토리를 삽입하고 생성하지 않는 이유는 무엇입니까? 사용자 엔터티 – bxN5

+0

UserFactory의 내용을 공유 할 수도 있습니까? 도메인 엔티티 용 팩토리를 작성할 강력한 이유가 있습니까? 어쨌든, 나는 그러한 작업을 위해 컨트롤러 플러그인을 작성하려고 노력할 것이다. – edigu

+0

@Roman 내 공장에서는 서비스 검색자를 필요로하기 때문에 공장을 투입하면 서비스 패턴을 삽입해야합니다. 따라서 나는 이것을 할 수 없다. 어떤 아이디어? – thexpand

답변

0

가장 좋은 방법은 컨트롤러에 사용자 개체의 새 인스턴스를 주입하는 것입니다. 컨트롤러 공장은 다음과 같아야합니다

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

} 

을 컨트롤러, 사용자의 새로운 인스턴스가 필요할 때, 그것은 단순히 PHP의 클론 함수를 호출하여 생성 할 수 있습니다 내부. 공장은 사용자 클래스의 새로운 인스턴스를 생성하는 서비스 로케이터를 사용하기 때문에

<?php 

namespace User\Controller\Core; 

use User\Entity\User; 
use Zend\View\Model\ViewModel; 
use Zend\Mvc\Controller\AbstractActionController; 

class UserAdminController extends AbstractActionController { 

    /** 
    * @var User 
    */ 
    public $user; 

    /** 
    * @param User $user 
    */ 
    public function __construct(User $user){ 
     $this->user = $user; 
    } 
    /** 
    * @return ViewModel 
    */ 
    public function indexAction(){ 
     if($this->getRequest()->isPost()){ 
      $usersData = $this->params()->fromPost("usersData"); 
      foreach($usersData as $userData){ 
       $newUser = clone $this->user; 
       $newUser->fromArray($userData); 
       $newUser->save(); 
      } 
     } 

     return ViewModel(); 
    } 

} 

컨트롤러에 UserFactory를 주입, 하지 옵션입니다 : 여기에 그것을 수행하는 방법의 컨트롤러 예를 들어 동작입니다. 팩토리가 컨트롤러에 주입되고 있다면, 서비스 로케이터도 삽입해야하지만, 이것은 안티 패턴으로 간주되며 더이상 사용되지 않으며 ZendFramework3에서 나쁜 습관으로 간주됩니다.

관련 문제