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 {
/**
* The form builder.
*
* @var \Drupal\Core\Form\FormBuilder
*/
protected $formBuilder;
/**
* ModalFormContactController constructor.
*
* @param \Drupal\Core\Form\FormBuilder $form_builder
* The form builder.
*/
public function __construct(FormBuilder $form_builder) {
$this->formBuilder = $form_builder;
}
/**
* {@inheritdoc}
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The Drupal service container.
*
* @return static
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('form_builder')
);
}
/**
* Callback for modal form.
*/
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(Dependency Injection、依存性注入)のコードの部分を説明しましょう。
namespace Drupal\drupalbook\Controller;
まず、namespace(名前空間)を指定します。これは、このファイルが置かれている場所で、drupalbook はモジュールのマシン名です。
use Symfony\Component\DependencyInjection\ContainerInterface;
ContainerInterface クラスをインポートします。後でService Containerからオブジェクトを取得するために使用します。
/**
* The form builder.
*
* @var \Drupal\Core\Form\FormBuilder
*/
protected $formBuilder;
Service Containerから受け取ったオブジェクトを保存するプロパティを宣言します。@var \Namespace コメントは、IDEがオートコンプリートでオブジェクトのどのメソッドを表示すべきかを理解するのに役立ちます。
/**
* ModalFormContactController constructor.
*
* @param \Drupal\Core\Form\FormBuilder $form_builder
* The form builder.
*/
public function __construct(FormBuilder $form_builder) {
$this->formBuilder = $form_builder;
}
次に、コンストラクターのパラメーターでService containerからオブジェクトを受け取る必要があります。このオブジェクトは次のcreate()メソッドで作成され、ここではそのオブジェクトを受け取って、上で宣言した $formBuilder プロパティに保存します。新しいサービスを接続する場合は、__construct() にパラメーターを1つずつ追加する必要があります。つまり、10個のサービスを接続する場合は、10個のパラメーターになります。
/**
* {@inheritdoc}
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The Drupal service container.
*
* @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)を使用します。
これで、Service Containerのオブジェクトをクラスのメソッドで使用できます:
/**
* Callback for modal form.
*/
public function openModalForm() {
...
$modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
...
}