Как сконфигурировать сервис с помощью конфигуратора
Дата обновления перевода 2023-06-30
Как сконфигурировать сервис с помощью конфигуратора
Конфигуратор сервиса - это функция сервис-контейнера, которая позволяет вам использовать вызываемое, чтобы сконфигурировать сервис после его инстанциирования.
Конфигуратор сервиса может быть использован, к примеру, когда у вас есть сервис, который требует сложной установки, основанной на настройках конфигурации, исходящих из разных источников или сервисов. Используя внешний конфигуратор, вы можете поддерживать реализацию сервиса в чистоте и держать её отдельно от других объектов, которые предоставляют необходимую конфигурацию.
Ещё один пример использования - когда у вас есть множество объектов, которые совместно используют общую конфигурацию, или которые должны быть похожим образом сконфигурированы во время прогона.
Например, представьте, что у вас есть приложение, где вы оправляtnt разные
виды электронных писем пользователям. Письма пропускаются через различные
программы форматирования, которые могут быть включены или нет, в зависимости
от некоторых динамических установок приложения. Вы начинаете определять класс
NewsletterManager
таким образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Mail/NewsletterManager.php
namespace App\Mail;
class NewsletterManager implements EmailFormatterAwareInterface
{
private $enabledFormatters;
public function setEnabledFormatters(array $enabledFormatters): void
{
$this->enabledFormatters = $enabledFormatters;
}
// ...
}
а также класс GreetingCardManager
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Mail/GreetingCardManager.php
namespace App\Mail;
class GreetingCardManager implements EmailFormatterAwareInterface
{
private $enabledFormatters;
public function setEnabledFormatters(array $enabledFormatters): void
{
$this->enabledFormatters = $enabledFormatters;
}
// ...
}
Как упоминалось ранее, целью являетя установить программы форматирования во
время прогона, в зависимости от настроек приложения. Чтобы сделать это, у вас
также есть класс EmailFormatterManager
, который отвечает за загрузку и
валидацию программ форматирования, включённых в приложении:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// src/Mail/EmailFormatterManager.php
namespace App\Mail;
class EmailFormatterManager
{
// ...
public function getEnabledFormatters(): array
{
// код для конфигурации того, какие программы форматирования использовать
$enabledFormatters = [...];
// ...
return $enabledFormatters;
}
}
Если вашей целью является избежать объединения NewsletterManager
и
GreetingCardManager
с EmailFormatterManager
, то вы можете захотеть
создать класс конфигуратора для конфигурирования этих экземпляров:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// src/Mail/EmailConfigurator.php
namespace App\Mail;
class EmailConfigurator
{
private $formatterManager;
public function __construct(EmailFormatterManager $formatterManager)
{
$this->formatterManager = $formatterManager;
}
public function configure(EmailFormatterAwareInterface $emailManager): void
{
$emailManager->setEnabledFormatters(
$this->formatterManager->getEnabledFormatters()
);
}
// ...
}
Работа EmailConfigurator
- внедрять включённые программы форматирования
в NewsletterManager
и GreetingCardManager
, потому что они не знают,
откуда появились включённые программы форматирования. С другой стороны,
EmailFormatterManager
содержит данные о включенных программах форматирования
и о том, как их загружать, поддерживая единый принцип ответственности.
Tip
В то время, как этот пример использует метод PHP-класса, конфигураторы могут быть любым PHP-вызываемым, включая функции, статические методы и методы сервисов.
Использование конфигуратора
Вы можете сконфигурировать конфигуратор сервиса, используя опцию configurator
. Если вы
используете конфигурацию services.yml по умолчанию ,
то все классы уже загружены как сервисы. Всё, что вам нужно сделать, это точно определить configurator
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# config/services.yaml
services:
# ...
# Регистрирует все 4 класса как сервисы, включая App\Mail\EmailConfigurator
App\:
resource: '../src/*'
# ...
# переопределить сервисы, чтобы установить конфигуратор
App\Mail\NewsletterManager:
configurator: ['@App\Mail\EmailConfigurator', 'configure']
App\Mail\GreetingCardManager:
configurator: ['@App\Mail\EmailConfigurator', 'configure']
Сервисы можно конфигурировать с помощью вызываемых конфигураторов (заменяя метод
configure()
на __invoke()
), опустив имя метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# config/services.yaml
services:
# ...
# регистрирует все классы как сервисы, включая App\Mail\EmailConfigurator
App\:
resource: '../src/*'
# ...
# переопределить сервисы, чтобы установить конфигуратор
App\Mail\NewsletterManager:
configurator: '@App\Mail\EmailConfigurator'
App\Mail\GreetingCardManager:
configurator: '@App\Mail\EmailConfigurator'
Вот и всё! При запрашивании сервиса AppBundle\Mail\NewsletterManager
или
AppBundle\Mail\GreetingCardManager
, созданный экземпляр вначале будет передан
в метод EmailConfigurator::configure()
.