Como injetar valores de configuração nos serviços?

8

No Symfony 2, ao definir um serviço, é possível injetar parâmetros de configuração referenciando-os com %parameter.name%strings. Por exemplo:

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

Mas qual é a abordagem correta do Drupal 8 para injetar valores de configuração nos serviços? Claro que não quero usar \Drupal::config()dentro de uma classe de serviço. A passagem de valores de configuração sempre que um serviço é referenciado também não faz muito sentido.

Eu sei que posso injetar o próprio serviço de configuração e obter valores de configuração, mas isso parece um pouco ruim porque meu próprio serviço sabe ler dados do serviço de configuração. Por exemplo:

# 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');
  }
}

Existe alguma outra maneira de fazer isso?

SiliconMind
fonte
11
A abordagem D8 é usar o @config.factoryserviço para obter a configuração do serviço de configuração. Isso ocorre porque o serviço de configuração pode ser substituído e não necessariamente obtendo seus valores de configuração do mesmo local.
mradcliffe

Respostas:

7

Você pode usar uma fábrica para o seu app.mailerserviço. A fábrica cuida de recuperar a configuração para o serviço. O serviço pode ficar dissociado do serviço de configuração e não precisa saber como os parâmetros de configuração são nomeados.

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;
  }
}
Pierre Buyle
fonte
11
Estou confuso, porque esperava ver 2 definições de serviço, semelhantes aos exemplos fornecidos em webomelette.com/more-complex-services-using-factories-drupal-8 . Dado este exemplo, como posso injetar outro serviço na Mailerclasse ?
Miloš Kroulík 27/10
3

É assim que se faz. A configuração pode mudar no tempo de execução, a definição de serviço geralmente é mantida e a reulução é cara. Supondo que seja a configuração que você deseja que os usuários alterem.

Caso contrário, você pode usar parâmetros, como no exemplo do symfony. Em seguida, você pode colocar sua configuração em services.yml em sites / padrão. Mas você só pode alterá-lo alterando o código e reconstruindo o contêiner.

Berdir
fonte
OK, isso significa basicamente que um serviço precisa saber como os parâmetros de configuração são nomeados para obtê-los no serviço de fábrica de configuração. Um pouco estranho e torna os testes mais complicados. Existe algum tipo de esboço de fábrica de configuração para fins de teste?
SiliconMind