Manière correcte d'appeler un service dans un contrôleur

10

Je suis nouveau dans les services (et drupal 8!) Et j'essaie de comprendre les services. Je pense que je fais peut-être juste la création d'une manière dépassée. Ce que je veux faire, c'est faire de mon 'bonjour générateur' un service et l'appeler dans un autre contrôleur avec ce qui suit:

DBController.php

namespace Drupal\db\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\db\DbServices\HelloGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;


class DBController extends ControllerBase
{
private $helloGenerator;

public function __construct(HelloGenerator $x) {
    $this->helloGenerator = $x;
}
public function say($count) {
    $hello = $this->helloGenerator->getHello($count);

    return new Response($hello);
}

public static function create(ContainerInterface $container) {
    $x = $container->get('db.hello_generator');
    return new static ($x);
}
}

HellGenerator.php

espace de noms Drupal \ db \ DbServices;

class HelloGenerator {

public function getHello($count) {
    $foo = 4 + 4 + 4;
    return $foo . ' ' . $count;
}

}

db.services.yml

services:
  db.hello_generator:
     class: Drupal\db\DbServices\HelloGenerator

db.db_says:
  path: /db/says/{count}
  defaults:
    _controller: '\Drupal\db\Controller\DBController::say'
  requirements:
    _permission: 'access content'
karl
la source
Vous pouvez suivre le document . C'est la bonne façon d'appeler un service dans un contrôleur
MrD

Réponses:

22

Il y a 3 questions ici:

  1. Comment créer un contrôleur?
  2. Comment créer un service?
  3. Comment utiliser les services dans un contrôleur?

1. Créez un contrôleur

1.1 Ajoutez une classe de contrôleur - vous l'avez fait. Pour les autres, voir la documentation Drupal

1.2 Ajoutez un fichier de routage - il semble que cela manque dans votre code:

my_module.routing.yml

my_module.my_route_name:
  path: '/my/path'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyController::myAction'
  requirements:
    _permission: 'access content'

voir la documentation Drupal

2. Créez un service

2.1 Ajoutez une classe de service - vous l'avez fait.

2.2 Ajoutez un fichier de routage - vous l'avez fait bien qu'il contienne du code supplémentaire qui appartient au fichier de routage. C'est tout ce dont vous avez besoin:

my_module.services.yml

services:
  my_module.my_service:
    class: Drupal\my_module\Service\MyService

voir la documentation Drupal

3. Utiliser des services dans un contrôleur

Tu l'as fait. Voici une référence pour les autres:

3.1 Remplacer la create()méthode

La classe contrôleur hérite de cette méthode class ControllerBase. Son rôle est de créer l'objet contrôleur. Regardez l'argument de la méthode: il est passé le conteneur de services. Extrayez les services dont vous avez besoin et transmettez-les au constructeur:

public static function create(ContainerInterface $container) {
    $my_service = $container->get('my_module.my_service');
    $other_service = $container->get('other_service');

    return new static($my_service, $other_service);
}

3.2 Initialiser les services dans __construct()

public function __construct($my_service, $other_service)
{
    $this->my_service = $my_service;
    $this->other_service = $other_service;
}

3.3 Commencez à utiliser les services

zendka
la source
4
Je souhaite que la documentation officielle soit plus dans ce style, ou au moins avait quelques articles de synthèse qui l'était. Court et concis avec un exemple générique facilement traduit en application réelle.
Nicolaj
A ne pas oublier: utilisez Symfony \ Component \ DependencyInjection \ ContainerInterface; en classe contrôleur
Atep
Bien que je sois totalement d'accord avec le commentaire de @ Nicolaj, cela ne fonctionne pas pour moi ... et je n'essaie même pas d'utiliser un service personnalisé! Tout ce que je veux faire, c'est créer une variable de membre de classe qui contient un objet de connexion à la base de données statique. Je suis habitué à utiliser des systèmes où la mise en commun des connexions et à ne jamais créer plus de connexions que nécessaire n'est la norme. Alors, comment pourrais-je implémenter quelque chose de similaire dans un contrôleur / formulaire Drupal?
Kenny83
Vous voudrez peut-être ouvrir une autre question @ Kenny83, mais avez-vous consulté api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/… ? Avec cela, vous pouvez faire quelque chose comme ceci: gist.github.com/glaux/f4f1517563ddb57fb98b9213802c1569
Nicolaj
@Nicolaj LOL merci d'avoir souligné le partenaire saignant: P Je connais bien le service de base de données et c'est ce que j'essaie de revenir de ma create()méthode. Je suppose que vous ne l' auriez pas dit que si si je ne l' avais pas manqué quelque chose d' autre qui aurait dû être évident ... Je suppose que le service fait des objets de connexion de la piscine?
Kenny83