In my Symfony 5 project I have 2 services and I autowire EntityManager
into both of them:
class MyService1 { public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } // ... }
and
class MyService2 { public function __construct(EntityManagerInterface $entityManager, MyService1 $myService1) { $this->entityManager = $entityManager; $this->myService1 = $myService1; } // ... }
I run some DB transaction inside one of the MyService2
functions:
$this->entityManager->getConnection()->beginTransaction();
and I call some helper function from MyService1
which uses also its own $entityManager
property and should be executed also inside that same DB transaction.
My question is: am I guaranteed that both Services will be autowired with the same (one and only) instance of $entityManager
? This is important because I need them both to work inside the same DB locking scope.
I did test it experimentally with dump()
function and they do seem to point to the very same instance. However I did not find in docs whether this is a sure behavior, or result of some random caching which is not guaranteed to happen.
Thanks!
Advertisement
Answer
Yes, you can expect it to be the same instance. The autowired instance is identical across the entire application. And a transaction started with the Entity Manager instance will be the same across different services, as long as you use the default connection.
This is basically the idea behind Dependency Injection. There is only one instance, and it is being shared across downstream services.
Looking at Design Patterns historically, this is the extension of the “Singleton” paradigm, where you would have a global class with a static instantiator. With Dependency Injection, the instance is managed by the DI container, but it is always the same (identical) object.
By the way, a lock is something different than a transaction. The transaction is only valid in the scope of your current connection, while a lock affects all connections until it is released.