logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动

12.15.1. 控制器中的 Dependency Injection

29/09/2025, by Ivan

Menu

在上一篇文章中,我们已经介绍了什么是 Dependencies Injection:

12.15. Services 和 Dependency Injection

在本文中,我们将展示一个控制器中使用 Dependency Injection 的代码示例。

/modules/custom/drupalbook/src/Controller/ModalFormContactController.php:

<?php

namespace Drupal\drupalbook\Controller;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormBuilder;

/**
 * ModalFormContactController class.
 */
class ModalFormContactController extends ControllerBase {

  /**
   * 表单构建器.
   *
   * @var \Drupal\Core\Form\FormBuilder
   */
  protected $formBuilder;

  /**
   * ModalFormContactController 构造函数.
   *
   * @param \Drupal\Core\Form\FormBuilder $form_builder
   *   表单构建器.
   */
  public function __construct(FormBuilder $form_builder) {
    $this->formBuilder = $form_builder;
  }

  /**
   * {@inheritdoc}
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   Drupal 服务容器.
   *
   * @return static
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('form_builder')
    );
  }

  /**
   * 模态表单的回调.
   */
  public function openModalForm() {
    $response = new AjaxResponse();
    $modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
    $enquiry_title = $this->t("Send an enquiry to @business_name", ['@business_name' => $modal_form['business_name']['#value']]);
    $response->addCommand(new OpenModalDialogCommand($enquiry_title, $modal_form));

    return $response;
  }

}

让我们逐步解析 DI(依赖注入)的代码部分:

namespace Drupal\drupalbook\Controller;

首先,我们定义命名空间 (namespace),表示该文件所在的位置,其中 drupalbook 是你模块的机器名。

use Symfony\Component\DependencyInjection\ContainerInterface;

引入 ContainerInterface 类,稍后我们将通过它从 Service Container 获取对象。

  /**
   * 表单构建器.
   *
   * @var \Drupal\Core\Form\FormBuilder
   */
  protected $formBuilder;

声明一个属性,用来存放从 Service Container 获取到的对象。注释中的 @var \Namespace 可以帮助 IDE 显示对象的自动补全方法。

  /**
   * ModalFormContactController 构造函数.
   *
   * @param \Drupal\Core\Form\FormBuilder $form_builder
   *   表单构建器.
   */
  public function __construct(FormBuilder $form_builder) {
    $this->formBuilder = $form_builder;
  }

接下来,在构造函数中我们通过参数接收 Service Container 提供的对象,并将其存入上面声明的属性 $formBuilder 中。如果你需要引入多个服务,只需要在 __construct() 中按顺序逐个添加参数即可。例如要引入 10 个服务,就会有 10 个参数。

  /**
   * {@inheritdoc}
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   Drupal 服务容器.
   *
   * @return static
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('form_builder')
    );
  }

create() 方法中,我们通过 Service Container 获取对象并返回给构造函数的参数 $form_builder,随后被保存到属性 $formBuilder 中。请注意变量命名规范:从 Service Container 获取的对象参数通常用小写下划线风格($form_builder),而类属性使用 camelCase 小驼峰($formBuilder)。

最后,我们就可以在类的方法中使用注入的服务对象了:

  /**
   * 模态表单的回调.
   */
  public function openModalForm() {
    ...
    $modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
    ...
  }