<?php namespace Domain; /** * @Entity */ class SomeEntity { …... private $someService; private $anotherService; …... public function setSomeService(SomeService $someService) { $this->someService = $someService; } public function setAnotherService2(AnotherService $anotherService) { $this->anotherService = $anotherService; } }
<?php namespace Persistence; use Doctrine\ORM\Events; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\Common\EventSubscriber; use DependencyInjection\Injector; class EntityConfigurator implements EventSubscriber { private $injector; public function __construct(Injector $injector) { $this->injector = $injector;; } public function getSubscribedEvents() { return [Events::postLoad]; } public function postLoad(LifecycleEventArgs $args) { $entity = $args->getEntity(); $this->injector->injectSevicesTo($entity); } }
$entityManager->getEventManager()->addEventSubscriber($entityConfigurator);
<?php namespace DependencyInjection; use Symfony\Component\DependencyInjection\ContainerBuilder; class Injector { const DOCTRINE_ENTITY_TAG = 'doctrine-entity'; /** *@var \Symfony\Component\DependencyInjection\ContainerBuilder */ private $container; private $configurableClasses = []; public function __construct(ContainerBuilder $container) { $this->container = $container; $this->prepareConfigurableClasses(); } private function prepareConfigurableClasses() { // foreach($this->container->findTaggedServiceIds(self::DOCTRINE_ENTITY_TAG) as $id => $tag) { // $definition = $this->container->findDefinition($id); // setter $this->configurableClasses[$definition->getClass()] = $definition->getMethodCalls(); } } public function injectSevicesTo($object) { if(!is_object($object) || !array_key_exists(get_class($object), $this->configurableClasses)) { return; } // DIC $parameter_bag = $this->container->getParameterBag(); $calls = $this->configurableClasses[get_class($object)]; foreach($calls as $call) { // $parametrized_references = $parameter_bag->resolveValue($call[1]); call_user_func_array(array($object, $call[0]), $this->container->resolveServices($parametrized_references)); } } }
services: ... .... entity-object-title: class: 'Domain \ SomeEntity' tags: [{name: "doctrine-entity"}] abstract: true calls: - [setSomeService, [@ some-service]] - [setSomeService2, [@ some-service2]] ... ..
entity-object-title
is an arbitrary name, used for descriptive purposes.abstract: true
- disable the ability to create a service directly. You can use public: false
for this purpose.calls
is a list of setters in which dependencies are injected.Source: https://habr.com/ru/post/173275/