我想知道EntityRepository类中EventDispatcher注入的最佳实践。
答案 0 :(得分:20)
首先,使用global
是very bad practice。我强烈建议你不要这样做
其次,将服务注入存储库似乎不是一个好主意。它经常会破坏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"
的的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 \库\ FooRepository 强>
class FooRepository extends EntityRepository
{
protected $dispatcher;
public function setEventDispatcher(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function findFooEntities(array $options = array())
{
$dispatcher = $this->dispatcher;
// ...
}
}
在控制器中使用它时,只需确保调用服务而不是存储库。
<强> DO 强>
$this->get('acme_foo.repository')->findFooEntities();
<强>不强>
$this->getDoctrine()->getManager()->getRepository('AcmeFooBundle:Foo')->findFooEntities();