Як використовувати ін'єкцію залежності від \ Drupal :: moduleHandler () до контролера?


15

Я використовую наступний рядок у класі контролера.

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

Pareview.sh передає мені це повідомлення про помилку.

\ Друпальські дзвінки слід уникати в класах, замість цього використовувати ін'єкцію залежності.

Як мені це зробити? Чи потрібно мені створити конструктор, створити метод чи послугу? Якщо так, то який код потрібен службі? Я знайшов приклад "Друпальські дзвінки слід уникати на заняттях, замість цього використовувати ін'єкцію залежності" для випадку, коли служба вже існує.


createперевантажить батьківський метод - тут ви можете ввести потрібні вам послуги. Конструктор дозволить вам призначити їх для змінних екземплярів у класі, тому ви можете використовувати$this->fooInjectedClass->methodName()
Кевін

У нас вже є питання з цього приводу? Якщо ні, то ми справді повинні зробити це канонічним.
mpdonadio

Відповіді:


21

У контролері ви надаєте послуги, використовуючи службовий контейнер. Наприклад 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')
    );  
  }

Тоді ви можете уникнути \Drupalдзвінків, скориставшись службою введення:

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

Ви можете вводити будь-яку службу, існуючу з ядра / contrib або служб, визначених у власному коді у *.services.ymlфайлі.

Щоб знайти ім'я основної служби, яке я зазвичай шукаю core.services.yml, тому що це найшвидший спосіб, коли ви працюєте над проектом drupal у своїй IDE.

Ви можете використовувати консоль Drupal, щоб перелічити всі сервіси, а не лише основні:

drupal debug:container

Ви також можете використовувати модуль Devel , який дозволяє шукати ім’я:

/devel/container/service

1
Таке питання / відповідь слід розширити, коли я погоджуюся, і внести свій внесок у документи drupal.org. Там є деякі , але я відчуваю, що приклади реального світу, як це, завжди допомагають.
Кевін

4
ControllerBaseКлас вже реалізує ContainerInjectionInterfaceінтерфейс. Не потрібно додавати implements ContainerInjectionInterfaceв клас, який розширюється ControllerBase.
kiamlaluno

Правильно, щойно помітив те саме, що і @kiamlaluno; буде радий оновити відповідь!
Стефанос
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.