Я хотел бы знать, что является лучшей практикой для инъекции EventDispatcher в классе EntityRepository.
Каков наилучший способ вставки EventDispatcher в EntityRepository?
Ответ 1
Во-первых, использование global
- это очень плохая практика. Я настоятельно рекомендую вам не делать этого.
Во-вторых, внедрение служб в репозиторий не кажется хорошей идеей. Он часто нарушает законы, такие как принцип единой ответственности.
Я бы создал менеджера, который будет обертывать методы вашего репозитория, и будет запускать события, которые вам нужны. См. как добавить репозиторий в службу для получения дополнительной информации.
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;
// ...
}
}
Просто убедитесь, что вы вызываете службу, а не репозиторий, когда используете ее в контроллере.
DO
$this->get('acme_foo.repository')->findFooEntities();
DO NOT
$this->getDoctrine()->getManager()->getRepository('AcmeFooBundle:Foo')->findFooEntities();