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