首页 > 解决方案 > 如何在 Symfony 4 中创建通用存储库

问题描述

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

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

所以我可以定义它的子类,例如:

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

但我收到了这个错误:

无法自动装配服务“App\Repository\AppRepository”:方法“__construct()”的参数“$entityClass”必须具有类型提示或明确给出值。

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

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

提前致谢

标签: phpdoctrine-ormsymfony4

解决方案


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

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

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

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


推荐阅读