Symfony 5 - 存储库 Class 从自定义 BaseRepository Class 扩展而不是 ServiceEntityRepository

Symfony 5 - Repository Class extend from custom BaseRepository Class instead of ServiceEntityRepository

假设我们有两个存储库 classes:

class CarrierRepository extends ServiceEntityRepository
{
    const ENTITY = 'carrier';

    /** @var PaginatorInterface $paginator */
    private $paginator;

    public function __construct(ManagerRegistry $registry, PaginatorInterface $paginator)
    {
        $this->paginator = $paginator;
        parent::__construct($registry, Carrier::class);
    }
.
.
.

class LocationRepository extends ServiceEntityRepository
{
    const ENTITY = 'location';

    /** @var PaginatorInterface $paginator */
    private $paginator;

    public function __construct(ManagerRegistry $registry, PaginatorInterface $paginator)
    {
        $this->paginator = $paginator;
        parent::__construct($registry, Location::class);
    }
.
.
.

并且在这两个存储库 classes 中,我们具有相同的逻辑,如下所示:

    public function search(array $searchParams)
    {
        $parameters = [];
        $qb = $this->createQueryBuilder(self::ENTITY);

        foreach ($searchParams['data'] as $key => $searchParam) {

            if (!empty($searchParam['param'])) {
                $entity = self::ENTITY;
                $operator = 'LIKE';
                $column = $searchParam['key'];
                $parameters[$searchParam['key']] = '%'.$searchParam['param'].'%';
.
.
.

如您所见,两个存储库 class 具有相同的依赖关系和相同的逻辑 - 除了实体 class - 在一个 class 中它是“载体”并且在另一个是“位置”。 我认为将其合并到 BaseRepository class 中是个好主意,如下所示:

class BaseRepository extends ServiceEntityRepository
{
    private $entity;

    /** @var PaginatorInterface $paginator */
    private $paginator;

    public function __construct($entity, ManagerRegistry $registry, PaginatorInterface $paginator)
    {
        $this->entity = $entity;
        $this->paginator = $paginator;
        parent::__construct($registry, $this->entity);
    }

    public function search(array $searchParams)
    {
        $parameters = [];
        $qb = $this->createQueryBuilder(self::ENTITY);

        foreach ($searchParams['data'] as $key => $searchParam) {

            if (!empty($searchParam['param'])) {
                $entity = self::ENTITY;
                $operator = 'LIKE';
                $column = $searchParam['key'];
                $parameters[$searchParam['key']] = '%'.$searchParam['param'].'%';
.
.
.

并扩展我的其他两个存储库而不是

ServiceEntityRepository

像这样使用我的 BaseRepository(CarrierRepository 的示例):

class CarrierRepository extends BaseRepository
{
    const ENTITY = 'carrier';

    /** @var PaginatorInterface $paginator */
    private $paginator;

    public function __construct(ManagerRegistry $registry, PaginatorInterface $paginator)
    {
        $this->paginator = $paginator;
        parent::__construct(Carrier::class, $registry, $paginator);
    }
.
.
.

这不起作用 - 它会给我这个错误:

Cannot autowire service "App\Repository\BaseRepository": argument "$entity" of method "__construct()" has no type-hint, you should configure its value explicitly.

问题: 我如何为所有使用相同属性和逻辑的 EntityRepositories 实现 BaseRepository,这样我就不必一次又一次地在我的所有 Repository classes 中实现整个逻辑? 我想要一个基本存储库,其中包含整个逻辑,我的所有存储库 classes 都可以使用相同的代码。

下面是我制作 BaseRepository 的方法:

abstract class BaseRepository extends ServiceEntityRepository
{
    protected string $entityClass;

    public function __construct(ManagerRegistry $registry, string $entityClass)
    {
        $this->entityClass = $entityClass;

        parent::__construct($registry, $entityClass);
    }
}

class CompanyUserRepository extends BaseRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, CompanyUser::class);
    }
}

重点是使 BaseRepository 抽象化,禁用此 class 的“自动装配”。