Как сконфигурировать сервис с помощью конфигуратора¶
Конфигуратор сервиса - это функция сервис-контейнера, которая позволяет вам использовать вызываемое, чтобы сконфигурировать сервис после его инстанциирования.
Конфигуратор сервиса может быть использован, к примеру, когда у вас есть сервис, который требует сложной установки, основанной на настройках конфигурации, исходящих из разных источников или сервисов. Используя внешний конфигуратор, вы можете поддерживать реализацию сервиса в чистоте и держать её отдельно от других объектов, которые предоставляют необходимую конфигурацию.
Ещё один пример использования - когда у вас есть множество объектов, которые совместно используют общую конфигурацию, или которые должны быть похожим образом сконфигурированы во время прогона.
Например, представьте, что у вас есть приложение, где вы оправляtnt разные
виды электронных писем пользователям. Письма пропускаются через различные
программы форматирования, которые могут быть включены или нет, в зависимости
от некоторых динамических установок приложения. Вы начинаете определять класс
NewsletterManager
таким образом:
// src/AppBundle/Mail/NewsletterManager.php
namespace AppBundle\Mail;
class NewsletterManager implements EmailFormatterAwareInterface
{
private $enabledFormatters;
public function setEnabledFormatters(array $enabledFormatters)
{
$this->enabledFormatters = $enabledFormatters;
}
// ...
}
а также класс GreetingCardManager
:
// src/AppBundle/Mail/GreetingCardManager.php
namespace AppBundle\Mail;
class GreetingCardManager implements EmailFormatterAwareInterface
{
private $enabledFormatters;
public function setEnabledFormatters(array $enabledFormatters)
{
$this->enabledFormatters = $enabledFormatters;
}
// ...
}
Как упоминалось ранее, целью являетя установить программы форматирования во
время прогона, в зависимости от настроек приложения. Чтобы сделать это, у вас
также есть класс EmailFormatterManager
, который отвечает за загрузку и
валидацию программ форматирования, включённых в приложении:
// src/AppBundle/Mail/EmailFormatterManager.php
namespace AppBundle\Mail;
class EmailFormatterManager
{
// ...
public function getEnabledFormatters()
{
// код для конфигурации того, какие программы форматирования использовать
$enabledFormatters = array(...);
// ...
return $enabledFormatters;
}
}
Если вашей целью является избежать объединения NewsletterManager
и
GreetingCardManager
с EmailFormatterManager
, то вы можете захотеть
создать класс конфигуратора для конфигурирования этих экземпляров:
// 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
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'
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<!-- app/config/services.xml --> <?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <prototype namespace="AppBundle\" resource="../../src/AppBundle/*" ... /> <service id="AppBundle\Mail\NewsletterManager"> <configurator service="AppBundle\Mail\EmailConfigurator" method="configure" /> </service> <service id="AppBundle\Mail\GreetingCardManager"> <configurator service="AppBundle\Mail\EmailConfigurator" method="configure" /> </service> </services> </container>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// app/config/services.php use AppBundle\Mail\EmailConfigurator; use AppBundle\Mail\EmailFormatterManager; use AppBundle\Mail\GreetingCardManager; use AppBundle\Mail\NewsletterManager; use Symfony\Component\DependencyInjection\Reference; // ... $container->autowire(EmailFormatterManager::class); $container->autowire(EmailConfigurator::class); $container->autowire(NewsletterManager::class) ->setConfigurator(array(new Reference(EmailConfigurator::class), 'configure')); $container->autowire(GreetingCardManager::class) ->setConfigurator(array(new Reference(EmailConfigurator::class), 'configure'));
New in version 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()
.
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.