Как ввести значения конфигурации в сервисы?

8

В Symfony 2 при определении службы можно вводить параметры конфигурации, ссылаясь на них со %parameter.name%строками. Например:

services:
  app.mailer:
    class:        AppBundle\Mailer
    arguments:    ['%app.mailer.transport%']

Но каков правильный подход Drupal 8 к внедрению значений конфигурации в сервисы? Конечно, я не хочу использовать \Drupal::config()внутри класса обслуживания. Передача значений конфигурации каждый раз при обращении к услуге также не имеет особого смысла.

Я знаю, что могу внедрить сам сервис конфигурации, а затем получить от него значения конфигурации, но это выглядит немного глупо, так как сам мой сервис знает, как читать данные из сервиса конфигурации. Например:

# Yaml service configuration
services:
  app.mailer:
    class:        mail_module\Mailer
    arguments:    ['@config.factory']

PHP

<?php
class Mailer {
  public function __construct($config) {
    $this->mailTransport = $config->get('mail.config')->get('transport');
  }
}

Есть ли другой способ сделать это?

SiliconMind
источник
1
Подход D8 заключается в использовании @config.factoryслужбы для получения конфигурации из службы конфигурации. Это связано с тем, что служба конфигурации может быть переопределена и не обязательно получать свои значения конфигурации из того же места.
Мрадклифф

Ответы:

7

Вы можете использовать фабрику для вашего app.mailerобслуживания. Фабрика заботится о получении конфигурации для службы. Служба может оставаться отделенной от службы конфигурации, и ей не нужно знать, как называются параметры конфигурации.

services:
  app.mailer:
    class:       Drupal/mail_module/Mailer
    factory:      Drupal/mail_module/MailerFactory:create
    arguments:    ['@config.factory']


class MailerFactory {
  static function create($config) {
    return new Mailer($config->get('mail.config')->get('transport'));
  }
}

class Mailer {
  public function __construct($transport) {
    $this->mailTransport = $transport;
  }
}
Пьер Буйль
источник
1
Я запутался, потому что ожидал увидеть 2 определения сервисов, аналогично примерам, приведенным в webomelette.com/more-complex-services-using-factories-drupal-8. Учитывая этот пример, как я могу внедрить другой сервис в Mailerкласс ?
Милош Кроулик,
3

Это способ сделать это. Конфигурация может изменяться во время выполнения, определение службы обычно сохраняется, а повторное использование является дорогостоящим. Предполагая, что это конфигурация, которую вы хотите, чтобы пользователи изменили.

Если это не так, вы можете использовать параметры, как в примере с Symfony. Затем вы можете поместить свою конфигурацию в services.yml в sites / default. Но вы можете изменить его только путем изменения кода и перестройки контейнера.

Berdir
источник
Итак, это в основном означает, что службе необходимо знать, как называются параметры конфигурации, чтобы получить их от службы фабрики конфигурации. Немного неловко и усложняет тестирование. Есть ли какая-то заглушка фабрики конфигурации для целей тестирования?
SiliconMind
3

Вы можете использовать службу фабрики или конфигуратора, которая знает о том, как работает фабрика конфигураций и т. Д., Что позволяет отделить вашу службу от фабрики конфигураций. HTTP-клиент в ядре имеет конфигуратор, если вам нужен пример. См. Https://symfony.com/doc/current/service_container/configurators.html#using-the-configurator для документов.

larowlan
источник