2017-02-23 6 views
1

私は質問を策定する方法がわからないので、自由に編集してください。ZF2 Doctrine - 特定のIDを必要とする依存性注入を処理する方法

現在の状況は次のとおりです。 私はフォームクラスをインスタンス化するファクトリクラスを持っています。依存性注入(DI)は、コンストラクタインジェクションを介して行われます。私の問題は、このフォーム要素にfindbyメソッドが必要なDoctrine ObjectMultiCheckboxがあることです。このfindbyメソッドでは、特定のエンティティのIDが必要ですが、IDをファクトリクラスを介してフォームに渡すことはできません。

私の質問は、どうやってこの状況に対処できますか?最善のアプローチは何ですか?

class CustomerFormFactory implements FactoryInterface 
{ 
    /** 
    * Create service 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * @return Form 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $em = $serviceLocator->get('Doctrine\ORM\EntityManager'); 
     return new CustomerForm($em); 
    } 
} 

そして、私はこのようなサービスロケータを経由してフォームを取得:

のは、これが私のファクトリクラスであるとしましょう

$customerForm = $this->getServiceLocator()->get('CustomerForm'); 

にはどうすればサービスロケータにIDを渡すことができますか?フォーム要素に特定のIDが必要な場合は、DIとサービスの目的を壊しませんか?私はこのように自分で「古典的」な方法のために行くとフォーム要素をインスタンス化する必要があります

$customerForm = new CustomerForm(EntityManager $em, int $id); 

私は本当に私が何をすべきかわからないか、何これを処理するための最良の方法です。

答えて

3

フォームにオプションを挿入するには、ファクトリクラスのCreationOptionsを使用できます。

FormElementManager(フォーム要素のserviceLocator)の設定を開始することから始めましょう。あなたのModule.php

use Zend\ModuleManager\Feature\FormElementProviderInterface; 

class Module implements FormElementProviderInterface 
{ 
    // your module code 

    public function getFormElementConfig() 
    { 
     return [ 
      'factories' => [ 
       'myForm' => \Module\Form\MyFormFactory::class 
      ] 
     ]; 
    } 
} 

、我々はそれの依存関係を含むフォームを返す工場を、作成する必要がありconfigruationを設定した後。また、フォームクラス内で再利用できるオプションを挿入します。

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\MutableCreationOptionsTrait; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class MyFormFactory implements FactoryInterface 
{ 
    use MutableCreationOptionsTrait; 

    /** 
    * Create service 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * 
    * @return mixed 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     return new MyForm(
      $serviceLocator->getServiceLocator()->get('Doctrine\ORM\EntityManager'), 
      'MyForm', 
      $this->getCreationOptions() 
     ); 
    } 
} 

ではなく、このよう \Zend\ServiceManager\FactoryInterface\Zend\ServiceManager\Factory\FactoryInterfaceを使用することをお勧めしZF3を使用してZF3が工場を使用して起こっている方法です。上記の例では、ZF2(v2.7.6 zendframework/zend-servicemanager)バージョンを使用しました。それをZF3バージョンに置き換えるには、クラス Zend\ServiceManager\FactoryInterface::classのコメントを参照してください。

我々はFormElementManagerクラスに::get('myForm', ['id' => $id])を呼び出すときだから今、あなたはMyFormインスタンスを取得し、フォームのオプションは、我々が一緒に渡されてきたオプションが含まれています。

だからあなたのフォームが似たものになります。

class MyForm extends \Zend\Form\Form 
{ 
    public function __construct(
     \Doctrine\Common\Persistence\ObjectManager $entityManager, 
     $name = 'myForm', 
     $options = [] 
    ) { 
     parent::__construct($name, $options); 

     $this->setEntityManager($entityManager); 
    } 

    public function init() { 
     /** add form elements **/ 
     $id = $this->getOption('id'); 
    } 
} 

ます。また、フォームを作成し、EntityManagerを設定することができますが、それはすべてあなた次第です。コンストラクタインジェクションを使う必要はありません。

だからあなたのコントローラのexmaple:あなたはZF2.5 +またはZF3を使用しているとして、あなたはFormElementManagerを注入するために持っているので、

$myForm = $this->getServiceManager()->get('FormElementManager')->get('myForm', ['id' => 1337]); 
$options = $myForm->getOptions(); 
// your options: ['id' => 1337] 

あなたのコントローラ内ServiceManagerまたはロケータを持っていない可能性がありますかFormクラスを工場でコントローラに追加します。

フォーム内に他の依存関係はなく、オプションを設定する場合は、各クラスのファクトリを作成する必要はありません。 InvokableFactory::classを再利用することもできます。これは、creationOptionsも挿入するためです。

+1

素晴らしい回答!ありがとうございました :) – Sepultura

関連する問題