Comment utiliser l'injection de dépendances sur \ Drupal :: moduleHandler () à un contrôleur?


15

J'utilise la ligne suivante dans une classe de contrôleur.

    \Drupal::moduleHandler()->alter('mymodule_myfunction', $plugin_items);

Pareview.sh me donne ce message d'erreur.

\ Les appels Drupal doivent être évités dans les classes, utilisez plutôt l'injection de dépendances.

Comment dois-je accomplir cela? Dois-je créer un constructeur, créer une méthode ou un service? Si oui, de quel code le service devrait-il avoir besoin? J'ai trouvé un exemple sur "Les appels Drupal devraient être évités dans les classes, utilisez plutôt l'injection de dépendance" pour un cas où un service existe déjà.


createsurchargera la méthode parent - ici vous pouvez injecter les services dont vous avez besoin. Le constructeur vous laissera ensuite les affecter aux variables d'instance dans la classe, afin que vous puissiez utiliser$this->fooInjectedClass->methodName()
Kevin

Avons-nous déjà une question à ce sujet? Sinon, nous devrions vraiment en faire un canon.
mpdonadio

Réponses:


21

Dans un contrôleur, vous injectez des services à l'aide du conteneur de services. Par exemple ModuleHandler:

namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;

class MyController extends ControllerBase {

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * Constructs a MyController object
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler service.
   */
  public function __construct(ModuleHandlerInterface $module_handler) {
    $this->moduleHandler = $module_handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('module_handler')
    );  
  }

Ensuite, vous pouvez éviter les \Drupalappels en utilisant le service injecté:

$this->moduleHandler->alter('mymodule_myfunction', $plugin_items);

Vous pouvez injecter n'importe quel service, ceux existants de core / contrib ou les services que vous avez définis dans du code personnalisé dans un *.services.ymlfichier.

Pour trouver un nom de service principal, je regarde généralement core.services.yml, car c'est le moyen le plus rapide lorsque vous travaillez sur un projet Drupal dans votre IDE.

Vous pouvez utiliser Drupal Console pour répertorier tous les services, pas seulement à partir du cœur:

drupal debug:container

Vous pouvez également utiliser le module Devel , qui vous permet de rechercher un nom:

/devel/container/service

1
Ce type de question / réponse devrait être développé si je suis d'accord et contribué aux documents de drupal.org. Il y a un peu là, mais je me sens des exemples du monde réel comme celui - ci toujours de l' aide.
Kevin

4
La ControllerBaseclasse implémente déjà l' ContainerInjectionInterfaceinterface. Il n'est pas nécessaire d'ajouter implements ContainerInjectionInterfaceà une classe qui s'étend ControllerBase.
kiamlaluno

À droite, je viens de remarquer la même chose que @kiamlaluno; serait grand de mettre à jour la réponse!
Stefanos Petrakis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.