php - 在 EntityRepository 中注入(inject) EventDispatcher 的最佳方法是什么?

标签 php symfony doctrine-orm

我想知道在 EntityRepository 类中注入(inject) EventDispatcher 的最佳实践是什么。

最佳答案

首先,使用 global 是一个 very bad practice .我强烈建议你不要这样做。
其次,将服务注入(inject)存储库似乎不是一个好主意。它经常会违反法律,例如 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();
    }
}

然后你可以在你的 Controller 中使用它,就像服务一样。

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

但是,如果您真的需要将事件调度程序注入(inject)到您的实体中,您可以这样做

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;

        // ...
    }
}

只要确保在 Controller 中使用它时调用的是服务而不是存储库。

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

不要

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

关于php - 在 EntityRepository 中注入(inject) EventDispatcher 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19380332/

相关文章:

Symfony:ManyToMany 表额外列

javascript - 在 WordPress 子主题中加载脚本时出现问题

php - 在PHP中计算两个X,Y坐标之间的距离

forms - Symfony2 中带有 formType 和 Doctrine2 的 jQuery 自动完成字段

javascript - 在 symfony 中预览多个上传的图像

php - 使用 "instanceof"的正确方法是什么?

symfony - Doctrine 2 如何防止丢失外键

php - 在 PHP 中使用 DOM 操作将特定的 <font> 标记替换为 <span>

php - "message": "Method Illuminate\\Auth\\SessionGuard::factory does not exist.",

php - 从所有迁移文件 symfony 学说生成一个迁移?