12.15.1. 控制器中的 Dependency Injection
在上一篇文章中,我们已经介绍了什么是 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');
...
}