如何在 Symfony 4 中创建通用存储库

How to make a generic repository in Symfony 4

我正在使用 Symfony 4,我有很多具有共同行为的存储库,所以我想避免重复代码。我试图以这种方式定义 parent 存储库 class:

<?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
}

所以我可以定义它的 children classes,例如:

<?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);
    }
}

但是我收到了这个错误:

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

我尝试设置类型提示,如 stringobject,但没有用。

有没有办法定义通用存储库?

提前致谢

autowire 的"gotchas" 之一是,默认情况下,autowire 会在src 下查找所有类 并尝试将它们制作成服务。在某些情况下,它最终会选择 类,例如您的 AppRepository,它不打算成为服务,然后在尝试自动装配它们时失败。

最常见的解决方案是明确排除这些 类:

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

另一种应该有效(未测试)的方法是使 AppRepository 抽象。 Autowire 将忽略摘要 类。存储库有点棘手,抽象 类 扩展非抽象 类 有点不寻常。

只需将您的 AppRepository 抽象化即可,例如

abstract class AppRepository {}