如何使用父服务管理通用依赖关系
随着您向应用程序添加更多功能,您很可能会开始拥有共享一些相同依赖关系的相关类。例如,您可能有多个需要 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()
。
父服务上的所有属性都与子服务共享,但 shared
、abstract
和 tags
除外。这些属性*不会*从父服务继承。
提示
在所示示例中,共享相同配置的类也从 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 许可获得许可。