如何从Entity中postLoad的LifecycleEventArgs获取Container对象?

2022-01-24 00:00:00 containers php symfony entity symfony-2.6

我正在尝试使用 postLoad lifecycleCallbacks 将 Container 对象(在控制器中可用)注入到实体中.postLoad 方法的参数是 LifecycleEventArgs.根据转储输出,我可以在 LifecycleEventArgsEventManager 中看到容器属性(我想检索),但它似乎是私有属性并且没有 <EventManager 中的 code>getContainer() 方法.以下是我的代码.

I'm trying to inject the Container object (which is available in controllers) into an Entity using postLoad lifecycleCallbacks. The argument to the postLoad method is LifecycleEventArgs. I could see the container property (which I want to retrieve) in EventManager of LifecycleEventArgs according to the dump output, but it seems to be a private property and there is no getContainer() method in EventManager. The below is my code.

service.yml

service.yml

services:
    ibw.jobeet.entity.job.container_aware:
        class: IbwJobeetBundleEntityJob
        tags:
            - { name: doctrine.event_listener, event: postLoad }

IbwJobeetBundleEntityJob.php

IbwJobeetBundleEntityJob.php

<?php
namespace IbwJobeetBundleEntity;

use DoctrineORMMapping as ORM;
use DoctrineORMEventLifecycleEventArgs;
use SymfonyComponentValidatorConstraints as Assert;
use SymfonyComponentHttpFoundationFileUploadedFile;
use SymfonyComponentDependencyInjectionContainerAware;
use SymfonyComponentDependencyInjectionContainerInterface;

use IbwJobeetBundleUtilsJobeet;

/**
 * Job
 */
class Job
{
    //....
    /**
     * @var Container
     */
    protected $container;

    public function postLoad(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getEntity();
        $entityManager = $eventArgs->getEntityManager();
        $eventManager = $entityManager->getEventManager();
        echo '<pre>';
        DoctrineCommonUtilDebug::dump($eventManager, 3);

        // want to get $eventManager->container here

        exit;
    }
    //....
}

还有其他方法可以找回吗?

Is there any other way to retrieve it?

推荐答案

您可以使用 setter-injection 来调用容器的预定义方法(本例中为 setContainer())作为创建侦听器服务时的参数:

You can use setter-injection which result in a call to a predefined method (setContainer() in this case) with the container as an argument upon creation of the listener service:

services:
    ibw.jobeet.entity.job.container_aware:
        class: YourBundleDoctrineEventListenerJobListener
        calls:
            - [setContainer, ["@service_container"]]
        tags:
            - { name: doctrine.event_listener, event: postLoad }

现在容器被注入到你的监听器类的构造函数中:

Now the container is injected into the constructor of your listener class:

namespace YourBundleDoctrineEventListener;

use SymfonyComponentDependencyInjectionContainerInterface;
use DoctrineORMEventLifecycleEventArgs;

class JobListener
{
     /** @var ContainerInterface */
     protected $container;

     /** 
      * @param ContainerInterface @container
      */
     public function setContainer(ContainerInterface $container)
     {
          $this->container = $container;
     }

     public function postLoad(LifecycleEventArgs $eventArgs)
     {
         $entity = $eventArgs->getEntity();
         // do something with your entity here i.e.
         $entity->setFoo($this->container->getParameter('foo'));

这只是一个例子.请考虑只注入您真正需要的服务——而不是注入容器本身.您将获得更好的可测试性和性能奖励.

This is just an example. Please consider injecting only the services you really need - instead of injecting the container itself. You will be rewarded with better testability and performance.

相关文章