Comment injecter des valeurs de configuration dans les services?

8

Dans Symfony 2 lors de la définition d'un service, il est possible d'injecter des paramètres de configuration en les référençant avec des %parameter.name%chaînes. Par exemple:

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

Mais quelle est la bonne approche Drupal 8 pour injecter des valeurs de configuration dans les services? Bien sûr, je ne veux pas utiliser \Drupal::config()dans une classe de service. Passer des valeurs de configuration chaque fois qu'un service est référencé n'a pas beaucoup de sens non plus.

Je sais que je peux injecter le service de configuration lui-même puis en obtenir des valeurs de configuration, mais cela semble un peu merdique car mon service lui-même sait lire les données du service de configuration. Par exemple:

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

Y a-t-un autre moyen de faire ça?

SiliconMind
la source
1
L'approche D8 consiste à utiliser le @config.factoryservice pour obtenir la configuration à partir du service de configuration. Cela est dû au fait que le service de configuration peut être remplacé et ne pas nécessairement obtenir ses valeurs de configuration au même endroit.
mradcliffe

Réponses:

7

Vous pouvez utiliser une usine pour votre app.mailerservice. L'usine prend soin de récupérer la configuration du service. Le service peut rester découplé du service de configuration et n'a pas besoin de savoir comment les paramètres de configuration sont nommés.

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
la source
1
Je suis confus, car je m'attendais à voir 2 définitions de service, similaires aux exemples donnés dans webomelette.com/more-complex-services-using-factories-drupal-8 , étant donné cet exemple, comment puis-je injecter un autre service à la Mailerclasse ?
Miloš Kroulík
3

C'est la façon de le faire. La configuration peut changer au moment de l'exécution, la définition du service est généralement persistante et la reconstitution est coûteuse. En supposant que c'est la configuration que vous souhaitez que les utilisateurs changent.

Si ce n'est pas le cas, vous pouvez utiliser des paramètres, tout comme l'exemple symfony. Ensuite, vous pouvez mettre votre configuration dans services.yml dans sites / default. Mais vous ne pouvez le changer qu'en changeant le code et en reconstruisant le conteneur.

Berdir
la source
OK, cela signifie donc essentiellement qu'un service doit savoir comment les paramètres de configuration sont nommés afin de les obtenir auprès du service d'usine de configuration. Un peu maladroit et complique les tests. Existe-t-il une sorte de talon d'usine de configuration à des fins de test?
SiliconMind