2013-10-15 9 views

答えて

16

まず、globalを使用するのは、very bad practiceです。私はあなたにこれをしないことを強く勧めます。
第2に、リポジトリにサービスを注入することは良い考えのようではありません。それはしばしばSingle Responsibility Principleのような法律を破ります。

リポジトリのメソッドをラップするマネージャを作成し、必要なイベントをトリガします。詳細については、how to inject repository to a serviceを参照してください。

services.yml

services: 
    my_manager: 
     class: Acme\FooBundle\MyManager 
     arguments: 
      - @acme_foo.repository 
      - @event_dispatcher 

    acme_foo.repository: 
     class: Acme\FooBundle\Repository\FooRepository 
     factory_service: doctrine.orm.entity_manager 
     factory_method: getRepository 
     arguments: 
      - "AcmeFooBundle:Foo" 

アクメ\ FooBundle \ MyManager

use Acme\FooBundle\Repository\FooRepository; 
use Symfony\Component\EventDispatcher\EventDispatcherInterface; 

class MyManager 
{ 
    protected $repository; 
    protected $dispatcher; 

    public function __construct(FooRepository $repository, EventDispatcherInterface $dispatcher) 
    { 
     $this->repository = $repository; 
     $this->dispatcher = $dispatcher; 
    } 

    public function findFooEntities(array $options = array()) 
    { 
     $event = new PreFindEvent; 
     $event->setOptions($options); 

     $this->dispatcher->dispatch('find_foo.pre_find', $event); 

     $results = $this->repository->findFooEntities($event->getOptions()); 

     $event = new PostFindEvent; 
     $event->setResults($results); 

     $this->dispatcher->dispatch('find_foo.post_find', $event); 

     return $event->getResults(); 
    } 
} 

次に、あなただけのサービスのように、あなたのコントローラで使用することができます。

$this->get('my_manager')->findFooEntities($options); 

あなた本当にがあなたのエンティティにイベントディスパッチャを注入する必要がある場合は、あなたはその後、この

services.yml

services: 
    acme_foo.repository: 
     class: Acme\FooBundle\Repository\FooRepository 
     factory_service: doctrine.orm.entity_manager 
     factory_method: getRepository 
     arguments: 
      - "AcmeFooBundle:Foo" 
     calls: 
      - [ "setEventDispatcher", [ @event_dispatcher ] ] 

を行うことができますあなたはちょうどsetEventDispatcherメソッドを追加する必要がありますあなたのリポジトリ。

アクメ\ FooBundle \リポジトリ\ FooRepository

class FooRepository extends EntityRepository 
{ 
    protected $dispatcher; 

    public function setEventDispatcher(EventDispatcherInterface $dispatcher) 
    { 
     $this->dispatcher = $dispatcher; 
    } 

    public function findFooEntities(array $options = array()) 
    { 
     $dispatcher = $this->dispatcher; 

     // ... 
    } 
} 

ただ、コントローラにそれを使用しているときに、リポジトリサービスを呼び出していないことを確認してください。

$this->get('acme_foo.repository')->findFooEntities(); 

が、私はここに同じ問題を抱えてカムませ

$this->getDoctrine()->getManager()->getRepository('AcmeFooBundle:Foo')->findFooEntities(); 
+0

を行うのですか、とあなたの答えは、理にかなっています。しかし、今やManagerには2つの責任があり、リポジトリをプロキシしてイベントを発生させます。これは非常に "賢明な"質問ですが、SRPを取得するためにリファクタリングをどこで停止しますか? – JorgeeFG

+0

@ JorgeeFG IMOでは、あなたのマネージャで与えられた 'OptionsResolver :: resolve($ options)'と 'ResultHandler :: handle($ results)'(どちらもイベントを呼び出す)をもう一度リファクタリングすることができます。マネージャは、3つのコンポーネントすべてを接続する単純なFacadeとして機能します。しかし、これらの2つのインターフェイスを追加すると、大部分がイベントハンドラで実行できるので、動作を変更することでほとんど改善/変更がないため、過剰な取得を開始するような気がします。 – Touki

関連する問題