Symfony2 - 从随机类访问存储库

时间:2015-02-17 15:49:18

标签: symfony

一旦我获得更多知识,我计划以不同的方式做到这一点,但是现在我正努力让事情发挥作用。

我已经准备好应有的一切。将警报添加到数据库后,我需要对该警报执行某些操作。所以我做了一个EventListener,它基本上调用了我在随机类

中需要的函数
<?php

namespace Nick\AlertBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Nick\AlertBundle\Entity\AvailabilityAlert;
use Nick\AlertBundle\Service\ApiService;

class AvailabilityAlertListener
{

    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if ($entity instanceof AvailabilityAlert) {
            $api = new ApiService();
            $api->addFlightsAction($entity);
        }
    }
}

现在ApiService类目前并不适合我的设计,它现在只是一个随机类。我传递了我的$实体,所以我可以对它执行一些操作。

我需要做的其中一个操作涉及实体自定义存储库类。所以我的班级ApiService看起来像这样

<?php

namespace Nick\AlertBundle\Service;

class ApiService
{
    public function executeTerminalCommand($entity){

        $em = $this->getDoctrine()->getManager();
        $worldspanCommand = $em->getRepository("NickAlertBundle:AvailabilityAlert")->getSpecificAlert($entity->getId());
    }
}

所以在EventListender中,我调用上面的函数并将它传递给实体。此函数应调用我的自定义存储库类中的函数。有了上述内容,我收到了错误

  

尝试在类上调用方法getDoctrine   Nick \ AlertBundle \ Service \ UapiService(500内部服务器错误)

我将如何实现这项工作?

由于

1 个答案:

答案 0 :(得分:1)

这个的两个解决方案

第一种解决方案(推荐)

ApiService类成为symfony2服务并注入 EntityManager ServiceContainer(以避免ServiceCircularReferenceException)(construct injection或{ {3}})所以你可以直接使用它。为此,您还需要将此新服务注入事件监听器。

您可以按照以下方式执行此操作(请参阅编辑)

1)让你的ApiService班级成为服务

your_bundle_name.api_service:
        class: Path\To\Your\Api\Service\Class
        arguments: [@doctrine.orm.entity_manager] #i.e.: constructor injection

2)修改您的ApiService班级

<?php

namespace Nick\AlertBundle\Service;

use Doctrine\ORM\EntityManager; //!IMPORTANT
class ApiService
{
    protected $em:

    public function __construct(EntityManager $em) 
    {
        $this->em = $em;
    }

    public function executeTerminalCommand($entity)
    {
        $worldspanCommand = $this->em->getRepository("NickAlertBundle:AvailabilityAlert")->getSpecificAlert($entity->getId());
    }
}

这可能导致ServiceCircularReferenceException我的解决方案是改变点1)和2)如下

1)让您的ApiService课程成为服务

your_bundle_name.api_service:
        class: Path\To\Your\Api\Service\Class
        arguments: [@service_container]

2)修改您的ApiService班级

<?php

namespace Nick\AlertBundle\Service;

use Symfony\Component\DependencyInjection\ContainerInterface as Container; //!IMPORTANT
class ApiService
{
    protected $sc;

    public function __construct(Container $sc) 
    {
        $this->sc = $sc;
    }

    public function executeTerminalCommand($entity)
    { 
        $em = $this->sc->get('doctrine.orm.entity_manager');
        $worldspanCommand = $em->getRepository("NickAlertBundle:AvailabilityAlert")->getSpecificAlert($entity->getId());
    }
}

3)修改您的事件侦听器服务以接受服务容器作为实例化的参数

your_listner_name:
    class: Path\To\Your\Listener\Class
    arguments: [@your_bundle_name.api_service]
    tags:
        - { name: doctrine.event_listener, event: postPersist }

4)修改您的事件监听器类

<?php

namespace Nick\AlertBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Nick\AlertBundle\Entity\AvailabilityAlert;
use Nick\AlertBundle\Service\ApiService;

class AvailabilityAlertListener
{
    protected $api_service;

    public function __construct(ApiService $api_service)
    {
        $this->api_service = $api_service;
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if ($entity instanceof AvailabilityAlert) {
            $this->api_service->addFlightsAction($entity);
        }
    }
}

第二种解决方案

直接将服务容器注入您的侦听器,让您的ApiService类接受实体管理器作为参数

您可以按照以下方式执行此操作

1)修改您的ApiService课程,使其接受实体经理

<?php

namespace Nick\AlertBundle\Service;

use Doctrine\ORM\EntityManager; //!IMPORTANT
class ApiService
{
    protected $em:

    public function __construct(EntityManager $em) 
    {
        $this->em = $em;
    }

    public function executeTerminalCommand($entity)
    {
        $worldspanCommand = $this->em->getRepository("NickAlertBundle:AvailabilityAlert")->getSpecificAlert($entity->getId());
    }
}

2)修改您的事件监听器类,如下所示

<?php

namespace Nick\AlertBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Nick\AlertBundle\Entity\AvailabilityAlert;
use Nick\AlertBundle\Service\ApiService;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;


class AvailabilityAlertListener
{
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if ($entity instanceof AvailabilityAlert) {
            $entity_manager = $args->getEntityManager();
            $api = new ApiService($entity_manager);
            $api->addFlightsAction($entity);
        }
    }
}