Declaring Doctrine repositories as services

Published on 2019-08-27 • Modified on 2019-08-27

This my preferred way to declare and use Doctrine repositories. It allows to directly inject it wherever you need. Moreover, you have auto-completion in the IDE (PhpStorm with the Symfony plugin for example) as the service class is known. It's not the case when directly using the Doctrine getRepository() function inside a controller.


# config/packages/doctrine.yaml
services:
    App\Entity\ArticleRepository:
        factory: ['@doctrine.orm.default_entity_manager', getRepository]
        arguments:
            - App\Entity\Article
Bonus, the snippet to run this code: 🎉
<?php declare(strict_types=1);

// src/Controller/Snippet/Snippet40Trait.php

namespace App\Controller\Snippet;

use App\Entity\ArticleRepository;

/**
 * I am using a PHP trait in order to isolate each snippet in a file.
 * This code should be called from a Symfony controller extending AbstractController (as of Symfony 4.2)
 * or Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Services are injected in the main controller constructor.
 *
 * @property ArticleRepository $articleRepo
 */
trait Snippet40Trait
{
    public function snippet40(): void
    {
        // In fact the article repository service is injected in the main controller constructor
        $articles = $this->articleRepo->findArticlesForLang('en');

        //  We've got autocompletion on the ArticleRepository functions like "findArticlesForLang".

        echo sprintf('%d posts found! 📚', count($articles));

        // That's it! 😁
    }
}