Внедрить сервис, вызвав `setContainer` внутри объекта после его запуска

Есть ли способ ввести @service_container в сущности (которые были помечены как игнорируемые через services.yaml)

Каталог игнорируемых сущностей как:

App\:
    resource: '../src/*'
    exclude:
        - '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

Но я хочу добавить сервисный контейнер один раз $entity = new Entity();

#
# manually inject container
#
App\Entity\Settings\ReceiptTemplate:
    class: App\Entity\Settings\ReceiptTemplate
    autowire: true
    public: true
    calls:
        - method: setContainer
          arguments:
            - '@service_container'

Я буду взаимодействовать с моей сущностью ContainerAwareInterface и добавление черты ContainerAwareTrait,

Могу ли я это сделать? Если так, как? Или как заставить это работать?:)

1 ответ

Один из способов сделать это, если инъекция нужна только при вызове объекта (что мне и нужно).

ПРИМЕР ВПРЫСКА КОНТЕЙНЕРА - наихудший случай, но это может привести к инъекции любой услуги индивидуально, менее ненавистной.

Я ценю любые более красивые способы, если это возможно:)

services.yaml:

services:
    # services.yaml
    App\EventSubscriber\ReceiptTemplateSubscriber:
    tags: { name: doctrine.event_subscriber }

Сущность с сеттером и методами, выполняющими работу:

<?php declare(strict_types=1);

namespace App\Entity;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\Validator\Constraints as Assert;
use Twig\Template;

/**
 * @ORM\Entity
 * @ORM\Table(name="template_receipt")
 */
class ReceiptTemplate implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(type="text", options={"default": ""})
     * @Assert\Length(min=1)
     */
    private $content = '';

    /**
     * @return int
     */
    public function getId(): int
    {
        return $this->id ?? 0;
    }

    /**
     * @return string
     */
    public function getContent(): string
    {
        return $this->content;
    }

    /**
     * @param AbstractProposal $proposal
     * @return string
     */
    public function getContentTemplate(AbstractProposal $proposal): string
    {
        return $this->createTemplate($proposal);
    }

    /**
     * @param string $content
     * @return self
     */
    public function setContent(string $content): self
    {
        $this->content = $content;
        return $this;
    }

    /**
     * @param AbstractProposal $proposal
     * @return string
     */
    private function createTemplate(AbstractProposal $proposal): string
    {
        /**
         * $this->>container -- IS AVAILABLE :)
         */

        return $this->container->get('twig')->render('core/receipt_template.html.twig', [
            'content'  => $this->content,
            'entity' => $proposal,
        ]);
    }
}
?>

Абонент настраивает мой сервис через сеттер:

<?php

declare(strict_types=1);

namespace App\EventSubscriber;

use App\Entity\ReceiptTemplate;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class ReceiptTemplateSubscriber
 *
 * @package App\EventSubscriber
 */
class ReceiptTemplateSubscriber implements EventSubscriber
{
    /** @var ContainerInterface */
    private $container;

    /**
     * ReceiptTemplateSubscriber constructor.
     *
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * @return array
     */
    public function getSubscribedEvents(): array
    {
        return [
            Events::postLoad,
        ];
    }

    /**
     * @param LifecycleEventArgs $event
     */
    public function postLoad(LifecycleEventArgs $event): void
    {
        $entity = $event->getEntity();

        if (!$entity instanceof ReceiptTemplate) {
            return;
        }

        $entity->setContainer($this->container);
    }
}
?>
Другие вопросы по тегам