EntityRepository クラスでの EventDispatcher インジェクションのベスト プラクティスは何かを知りたいです。
9082 次
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 に答える