So I wanted to answer your subquestion:
This is a bit annoying, so I'm curious whether Symfony has something
that acts like EntityManagerAwareInterface.
And I think there is a solution to do so (I use it myself).
The idea is that you slightly change your kernel so tha it checks for all services which implement the EntityManagerAwareInterface
and injects it for them.
You can also add write an EntityManagerAwareTrait
that implements the $entityManager
property and the setEntityManager()
setter. The only thing left after that is to implement/use the interface/trait couple the way you would do for the Logger for example.
(you could have done this through a compiler pass as well).
<?php
// src/Kernel.php
namespace App;
use App\Entity\EntityManagerAwareInterface;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use function array_key_exists;
class Kernel extends BaseKernel implements CompilerPassInterface
{
use MicroKernelTrait;
public function process(ContainerBuilder $container): void
{
$definitions = $container->getDefinitions();
foreach ($definitions as $definition) {
if (!$this->isAware($definition, EntityManagerAwareInterface::class)) {
continue;
}
$definition->addMethodCall('setEntityManager', [$container->getDefinition('doctrine.orm.default_entity_manager')]);
}
}
private function isAware(Definition $definition, string $awarenessClass): bool
{
$serviceClass = $definition->getClass();
if ($serviceClass === null) {
return false;
}
$implementedClasses = @class_implements($serviceClass, false);
if (empty($implementedClasses)) {
return false;
}
if (array_key_exists($awarenessClass, $implementedClasses)) {
return true;
}
return false;
}
}
The interface:
<?php
declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\EntityManagerInterface;
interface EntityManagerAwareInterface
{
public function setEntityManager(EntityManagerInterface $entityManager): void;
}
The trait:
<?php
declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\EntityManagerInterface;
trait EntityManagerAwareTrait
{
/** @var EntityManagerInterface */
protected $entityManager;
public function setEntityManager(EntityManagerInterface $entityManager): void
{
$this->entityManager = $entityManager;
}
}
And now you can use it:
<?php
// src/SomeService.php
declare(strict_types=1);
namespace App;
use Exception;
use App\Entity\EntityManagerAwareInterface;
use App\Entity\Entity\EntityManagerAwareTrait;
use App\Entity\Entity\User;
class SomeService implements EntityManagerAwareInterface
{
use EntityManagerAwareTrait;
public function someMethod()
{
$users = $this->entityManager->getRepository(User::Class)->findAll();
// ...
}
}