Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a generic repository in Symfony 4

I'm working with Symfony 4, I've a lot of repositories with common behaviour, so I want to avoid repeated code. I tried to define a parent repository class this way:

<?php
namespace App\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

class AppRepository extends ServiceEntityRepository {
    public function __construct(RegistryInterface $registry, $entityClass) {
        parent::__construct($registry, $entityClass);
    }

    // Common behaviour
}

So I would be able to define its children classes, for instance:

<?php
namespace App\Repository;

use App\Entity\Test;
use App\Repository\AppRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

class TestRepository extends AppRepository {
    public function __construct(RegistryInterface $registry) {
        parent::__construct($registry, Test::class);
    }
}

But I'm getting this error:

Cannot autowire service "App\Repository\AppRepository": argument "$entityClass" of method "__construct()" must have a type-hint or be given a value explicitly.

I tried setting type hinting like string, object but It didn't work.

Is there a way to define a generic repository?

Thanks in advance

like image 429
Genarito Avatar asked Dec 12 '18 16:12

Genarito


People also ask

How do I create a repository for a Symfony entity?

Just press Enter or specify the location of your entity folder, and it will create missing getters/setters & Repositories. The SymfonyMakerBundle allows you to create your own makers. So you could make a new one called make:repositories that will generate a repository for each entity found in the /Entity folder.

How to create missing getters/setters&repositories in Symfony?

Just press Enter or specify the location of your entity folder, and it will create missing getters/setters & Repositories. The SymfonyMakerBundle allows you to create your own makers.

How to add custom methods to the repository in Salesforce?

1. Create a folder for the custom methods in the bundle. We are going to create a folder that will contain our classes with custom methods for the repositories, is recommendable to create it in the root folder of your bundle ( next to controller,entity,form folders ). This folder will have the name Repository.

What makes a great generic repository?

The first building block needed for a great generic repository is a base model that the rest of our entities will inherit from. I've found that the advantages of a base entity can be... almost... endless. Most importantly it will give us a stable, base type that we can build our other entities with and also reference in our generic repository.


1 Answers

One of the "gotchas" of autowire is that by default, autowire looks for all classes under src and attempts to make them into services. In some cases it ends up picking up classes such as your AppRepository which are not intended to be services and then fails when it tries to autowire them.

The most common solution is to explicitly exclude these classes:

# config/services.yaml
App\:
    resource: '../src/*'
    exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Repository/AppRepository.php}'

Another approach that should work (not tested) is to make AppRepository abstract. Autowire will ignore abstract classes. Repositories are a bit tricky and having abstract classes extend non-abstract classes is somewhat unusual.

like image 107
Cerad Avatar answered Sep 21 '22 23:09

Cerad