11

EntityRepository クラスでの EventDispatcher インジェクションのベスト プラクティスは何かを知りたいです。

4

1 に答える 1

21

まず、 usingglobal非常に悪い習慣です。これを行わないことを強くお勧めします。
第二に、リポジトリにサービスを注入することは良い考えではないようです。単一責任原則などの法律に違反することがよくあります。

リポジトリのメソッドをラップし、必要なイベントをトリガーするマネージャーを作成します。詳細については、リポジトリをサービスに注入する方法を参照してください。

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"

Acme\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次に、メソッドをリポジトリに追加するだけです。

Acme\FooBundle\Repository\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();
于 2013-10-15T12:10:11.397 に答える