【Drupal】独自サービスを作成する

こちらのサイトではDRUPAL10に関連する記事を掲載しています。

グローバル変数を使用してサービスを使用

サービスを使用するには、基本的に静的と注入の 2 つの方法があります 。

1 つ目はサービス コンテナーへの静的呼び出しによって行われますが、2 つ目は依存性注入を使用して、 コンストラクター (または、まれにセッター メソッド) を介してオブジェクトを渡します。

静的には、グローバルを使用します \Drupalサービスをインスタンス化するクラス:

$service = \Drupal::service('hello_world.salutation');

これが1つ目のサービスを呼び出す方法で、Drupal7まで使用していたものです。

いくつかの人気のあるサービスには、 \Drupalクラス; 例えば、 \Drupal::entityTypeManager(). を検査することをお勧めします。 \Drupalクラスを調べて、短縮メソッドが利用可能なものを見てください。

コントローラー、サービス、プラグイン、または依存性注入がオプションであるその他のクラス内でサービスのインスタンス化の静的メソッドを使用するのは適切ではありません。 その理由は、サービスを使用する目的の多くが無効になるためです。この 2 つが結びついてテストが困難になるからです。 一方、インサイド フックの実装やその他の Drupal 固有の手続き型コードでは、選択の余地がなく、そうするのが普通です。

さらに、コードの一部が .moduleファイルが存在する必要があるという意味ではありません。 一般に、これらのモジュールには、フックの実装や、特定の命名規則に従う必要があるその他の実装などのみを含める必要があります。 また、無駄がなく、作業をサービスに委任する必要があります。

DIを使用してサービスを使用

サービスを使用する適切な方法は、 必要な場所にサービスを注入することです。 確かに、このアプローチは少し時間がかかりますが、進歩するにつれて、それは第二の性質になります. また、(レシーバーに基づいて) 依存関係を注入する方法がいくつかあるため、 ここでは説明しません。 代わりに、本書全体を通して適切なタイミングでそれらがどのように機能するかを見ていきます。 次のセクションでは、非常に重要な例を見ていきます。

コントローラーにサービスを注入する

Controller にいくつかのコードを追加する必要があります (通常、クラスの先頭に追加して、このコードを見たときにすぐにこのコードの存在を識別できるようにします)。

/**
 * @var \Drupal\hello_world\HelloWorldSalutation
 */
protected $salutation;
/**
 * HelloWorldController constructor.
 *
 * @param \Drupal\hello_world\HelloWorldSalutation $salutation
 */
public function __construct(HelloWorldSalutation $salutation) {
  $this->salutation = $salutation;
}
/**
 * {@inheritdoc}
 */
public static function create(ContainerInterface $container) {
  return new static(
    $container->get('hello_world.salutation')
  );
}

これに加えて、 ファイルの先頭に関連する使用ステートメントを含めるようにしてください。

use Drupal\hello_world\HelloWorldSalutation;
use Symfony\Component\DependencyInjection\ContainerInterface;

まず、Controller にコンストラクター メソッドを指定します。このメソッドは、サービスを引数として取り 、それをプロパティとして格納します。 クラスがインスタンス化された最初に起動されるメソッドです。

create()は、Service Container をパラメーターとして受け取り、Controller コンストラクターが必要とするサービスを自由に選択できます。 これは通常、クラスでの 2 番目のメソッドです。 メソッドが存在するかどうかを確認するのはCreateをみれば一目瞭然です。

では、この注射事業は実際にはどのように機能しているのでしょうか?

コントローラーはControllerBaseを継承しており、ControllerBaseContainerInjectionInterfaceをインプリメントしています。ContainerInjectionInterfaceインターフェイスで定義されたcreate()メソッドを置き換えて、コンテナを設定する処理を記述します。

create()メソッドは、Drupal の依存性注入パターンの主要なプラクティスです。 ただし、コンテナ全体をインスタンス化するクラスに決して渡してはならないということを覚えておいてください。

ただし、依存性注入の観点からは、サービスを返すヘルパー メソッドを使用しないことをお勧めします (たとえば、 entityTypeManager())。 残念ながら、サービスを静的にロードするため、この場合のベスト プラクティスではありません。 先ほど行ったように、代わりに自分で注入する必要があります。

サービスが注入されたので、それを使用して動的なレンダリングできます。

return [
  '#markup' => $this->salutation->getSalutation(),
];

この例について明確にしたいことの 1 つは、簡単にするためにキャッシュをクリアしたことです。 キャッシュが設定されていると、ページがキャッシュされ、間違った動作をする可能性があります。

呼び出されたコントローラー

ルート、コントローラー、およびサービスが何であるかがわかったので ができることも簡単に説明したいと思います 呼び出すこと、コントローラーをサービスとして定義し、ルーティング システムによって 。 言い換えれば、私たちが定義したように hello_world.salutationコントローラーとして機能する別のサービスを定義し、ルーティング ファイルで完全修飾クラス名の代わりにそのサービス ID を参照することができます。 次に、Drupal が、ユーザーがルートにアクセスしたときにサービス内のどのメソッドを呼び出すかを知るために、魔法を実装する必要があります。 __invokeサービス内のメソッド。 残りはほとんど同じように機能します。

この機能は Drupal 8.7 で導入されたもので、Action-Domain-Responder アーキテクチャ パターンの典型です。 今後は使用しませんが、利用可能であることを知っておいてください.

Drupal 9 Module Development - Third Edition
With its latest release, Drupal 9, the popular open source CMS platform has been updated with new functionalities for building complex Drupal apps with ease. Th...

出典

Drupal 9 Module Development - Third Edition
With its latest release, Drupal 9, the popular open source CMS platform has been updated with new functionalities for building complex Drupal apps with ease. Th...
このサイトに関するご意見・ご質問はこちらまで

この記事またはDrupalに関するご質問がございましたら、お気軽にお問い合わせください。

タイトルとURLをコピーしました