'New alternative for getDoctrine() in Symfony 5.4 and up
As my IDE points out, the AbstractController::getDoctrine() method is now deprecated.
I haven't found any reference for this deprecation neither in the official documentation nor in the Github changelog.
What is the new alternative or workaround for this shortcut?
Solution 1:[1]
As mentioned here:
Instead of using those shortcuts, inject the related services in the constructor or the controller methods.
You need to use dependency injection.
For a given controller, simply inject ManagerRegistry on the controller's constructor.
use Doctrine\Persistence\ManagerRegistry;
class SomeController {
    public function __construct(private ManagerRegistry $doctrine) {}
    public function someAction(Request $request) {
        // access Doctrine
        $this->doctrine;
    }
} 
    					Solution 2:[2]
You can use EntityManagerInterface $entityManager:
public function delete(Request $request, Test $test, EntityManagerInterface $entityManager): Response
{
    if ($this->isCsrfTokenValid('delete'.$test->getId(), $request->request->get('_token'))) {
        $entityManager->remove($test);
        $entityManager->flush();
    }
    return $this->redirectToRoute('test_index', [], Response::HTTP_SEE_OTHER);
}
    					Solution 3:[3]
As per the answer of @yivi and as mentionned in the documentation, you can also follow the example below by injecting Doctrine\Persistence\ManagerRegistry directly in the method you want:
// src/Controller/ProductController.php
namespace App\Controller;
// ...
use App\Entity\Product;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Response;
class ProductController extends AbstractController
{
    /**
     * @Route("/product", name="create_product")
     */
    public function createProduct(ManagerRegistry $doctrine): Response
    {
        $entityManager = $doctrine->getManager();
        $product = new Product();
        $product->setName('Keyboard');
        $product->setPrice(1999);
        $product->setDescription('Ergonomic and stylish!');
        // tell Doctrine you want to (eventually) save the Product (no queries yet)
        $entityManager->persist($product);
        // actually executes the queries (i.e. the INSERT query)
        $entityManager->flush();
        return new Response('Saved new product with id '.$product->getId());
    }
}
    					Solution 4:[4]
In my case, relying on constructor- or method-based autowiring is not flexible enough.
I have a trait used by a number of Controllers that define their own autowiring. The trait provides a method that fetches some numbers from the database. I didn't want to tightly couple the trait's functionality with the controller's autowiring setup.
I created yet another trait that I can include anywhere I need to get access to Doctrine. The bonus part? It's still a legit autowiring approach:
<?php
namespace App\Controller;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectManager;
use Symfony\Contracts\Service\Attribute\Required;
trait EntityManagerTrait
{
    protected readonly ManagerRegistry $managerRegistry;
    #[Required]
    public function setManagerRegistry(ManagerRegistry $managerRegistry): void
    {
        // @phpstan-ignore-next-line PHPStan complains that the readonly property is assigned outside of the constructor.
        $this->managerRegistry = $managerRegistry;
    }
    protected function getDoctrine(?string $name = null, ?string $forClass = null): ObjectManager
    {
        if ($forClass) {
            return $this->managerRegistry->getManagerForClass($forClass);
        }
        return $this->managerRegistry->getManager($name);
    }
}
and then
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Entity\Foobar;
class SomeController extends AbstractController
{
    use EntityManagerTrait
    public function someAction()
    {
        $result = $this->getDoctrine()->getRepository(Foobar::class)->doSomething();
        // ...
    }
}
If you have multiple managers like I do, you can use the getDoctrine() arguments to fetch the right one too.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | commonpike | 
| Solution 2 | Cadot.eu | 
| Solution 3 | fallais | 
| Solution 4 | Jan Klan | 
