跳到内容

如何使用父服务管理通用依赖关系

编辑此页

随着您向应用程序添加更多功能,您很可能会开始拥有共享一些相同依赖关系的相关类。例如,您可能有多个需要 doctrine.orm.entity_manager 服务和可选的 logger 服务的仓库类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Repository/BaseDoctrineRepository.php
namespace App\Repository;

use Doctrine\ORM\EntityManager;
use Psr\Log\LoggerInterface;

// ...
abstract class BaseDoctrineRepository
{
    protected LoggerInterface $logger;

    public function __construct(
        protected EntityManager $entityManager,
    ) {
    }

    public function setLogger(LoggerInterface $logger): void
    {
        $this->logger = $logger;
    }

    // ...
}

您的子服务类可能如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/Repository/DoctrineUserRepository.php
namespace App\Repository;

use App\Repository\BaseDoctrineRepository;

// ...
class DoctrineUserRepository extends BaseDoctrineRepository
{
    // ...
}

// src/Repository/DoctrinePostRepository.php
namespace App\Repository;

use App\Repository\BaseDoctrineRepository;

// ...
class DoctrinePostRepository extends BaseDoctrineRepository
{
    // ...
}

服务容器允许您扩展父服务,以避免重复的服务定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# config/services.yaml
services:
    App\Repository\BaseDoctrineRepository:
        abstract:  true
        arguments: ['@doctrine.orm.entity_manager']
        calls:
            - setLogger: ['@logger']

    App\Repository\DoctrineUserRepository:
        # extend the App\Repository\BaseDoctrineRepository service
        parent: App\Repository\BaseDoctrineRepository

    App\Repository\DoctrinePostRepository:
        parent: App\Repository\BaseDoctrineRepository

    # ...

在这种情况下,拥有一个 parent 服务意味着父服务的参数和方法调用应该用于子服务。具体来说,当 App\Repository\DoctrineUserRepository 实例化时,将注入 EntityManager 并调用 setLogger()

父服务上的所有属性都与子服务共享, sharedabstracttags 除外。这些属性*不会*从父服务继承。

提示

在所示示例中,共享相同配置的类也从 PHP 中的同一父类扩展而来。这完全不是必需的。您还可以将类似服务定义的公共部分提取到父服务中,而无需在 PHP 中扩展父类。

覆盖父依赖关系

有时您可能只想为一个子服务覆盖注入的服务。您可以通过在子类中指定它来覆盖大多数设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# config/services.yaml
services:
    # ...

    App\Repository\DoctrineUserRepository:
        parent: App\Repository\BaseDoctrineRepository

        # overrides the private setting of the parent service
        public: true

        # appends the '@app.username_checker' argument to the parent
        # argument list
        arguments: ['@app.username_checker']

    App\Repository\DoctrinePostRepository:
        parent: App\Repository\BaseDoctrineRepository

        # overrides the first argument (using the special index_N key)
        arguments:
            index_0: '@doctrine.custom_entity_manager'
本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可获得许可。
目录
    版本