如何使用父服務管理常見依賴關係
當您為應用程式新增更多功能時,您很可能會開始擁有相關的類別,這些類別共用一些相同的依賴關係。例如,您可能有多個儲存庫類別需要 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 授權條款發佈。