Внедрить сервис, вызвав `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);
}
}
?>