DIコンテナとは?依存性注入の仕組みを初心者向けにわかりやすく解説

プログラミングの記事を読んでいると、「DI」はなんとなく分かっても「コンテナって何?」で一度止まりませんか。

こんにちは、『ゴイノワ』のナギです。わたしも最初は、何かを入れておく箱くらいの意味なのかな、と名前のところで引っかかりました。

先に答えると、DIコンテナは必要な部品を用意して、必要な場所へ渡してくれる仕組みです。ここを起点にすると理解しやすくなります。

目次

DIコンテナとは何?

DIコンテナは、ソフトウェアの部品どうしの依存関係を管理し、必要なオブジェクトを生成して渡す仕組みです。DIは「Dependency Injection」の略です。

日本語では「依存性注入」や「依存性の注入」と呼ばれます。ただ、この訳だけを見ると余計に難しく感じるかもしれませんね。

DI

必要な部品を外から渡す仕組み

DIコンテナ

その部品の生成や受け渡しを担う仕組み

わたしなら、まず「DI」と「DIコンテナ」を同じものとして覚えないようにします。DIは考え方や手法で、コンテナはそれを助ける仕組み、と分けると腑に落ちます。

そもそも依存とは?

ここで一度止まったのが、「依存」という言葉でした。日常では少し重い響きがありますが、プログラムではもっと単純な関係を指します。

たとえば、注文を受け付けるプログラムがメール送信機能を使うなら、注文側はメール送信側を必要としています。この「必要としている関係」が依存です。

一つのクラスの中で必要な部品を直接作ることもできます。ただ、その部品を別のものへ替えたいとき、利用する側のコードまで書き換える場面が出てきます。

DIでは何が変わる?

DIでは、使う側が必要な部品を自分で作るのではなく、外から受け取ります。よく使われるのが、コンストラクタを通して受け取る方法です。

たとえるなら、料理人が畑へ野菜を取りに行くのではなく、必要な食材を厨房まで届けてもらう感じ。料理人は料理そのものに集中できます。

ナギ

「誰が部品を用意するの?」が次の疑問です

そこで登場するのがDIコンテナです。どの部品を使うかあらかじめ登録しておき、必要になったときに生成して渡す役割を担います。

DIコンテナがすること

DIコンテナの役割は製品によって差がありますが、基本を追うなら登録・生成・受け渡しの流れを見ると分かりやすいです。

項目内容
登録どの部品を使うかコンテナへ知らせる
生成必要になったオブジェクトを作る
受け渡し必要としているクラスへ渡す
寿命の管理オブジェクトを使い続ける範囲を扱う

SpringではIoCコンテナがオブジェクトの生成や設定、組み合わせを担います。.NETにも標準のサービスコンテナがあり、登録したサービスを必要な場所へ渡せます。

名前や具体的な使い方は環境ごとに違います。DIコンテナという名前の製品が一つあるわけではありません。ここは取り違えたくないところです。

使うと何がうれしい?

分かりやすい利点は、使う側と使われる側の結びつきを弱くしやすいことです。別の実装へ替えるときも、利用側へ手を入れずに済む場合があります。

テストでも利点があります。本番用の部品ではなく、テスト用に用意した部品へ差し替えやすくなるためです。

ただし、DIコンテナを入れれば自動的に良い設計になるわけではありません。登録する部品が増えるほど、どこで何を登録したか追う必要も出てきます。

IoCコンテナとの違い

DIコンテナを調べると、「IoCコンテナ」という言葉もよく出てきます。ここで似た名前が増えるので、少しややこしく感じるところなんですよね。

IoCは「Inversion of Control」の略で、日本語では「制御の反転」と訳されます。DIは、そのIoCを実現する方法の一つとして扱われます。

そのため、DIを扱う仕組みをIoCコンテナと呼ぶ資料もあります。Springの公式資料では「IoC Container」という呼び方が使われています。

Service Locatorとは別物

もう一つ、DIと並んで出てくるのがService Locatorです。どちらも部品どうしの強い結びつきを避けるために使われますが、受け取り方が違います。

DIでは外側から必要な部品を渡してもらいます。一方のService Locatorでは、使う側がロケーターへ「この部品をください」と探しに行く形です。

似た目的があるので、言葉だけ追うと混ざりやすいところ。わたしは「渡されるのがDI、取りに行くのがLocator」と先に覚えるほうがつかみやすいと思います。

コードではどう登場する?

実際の開発では、「サービスをコンテナへ登録する」「コンストラクタで受け取る」といった形でDIコンテナに触れることがあります。

たとえば.NETでは、インターフェースと実装の組み合わせをサービスとして登録できます。必要なクラス側では、そのインターフェースをコンストラクタで受け取ります。

JavaのSpringでも、コンテナがBeanと呼ばれるオブジェクトを生成し、依存するオブジェクトを渡します。書き方は違っても、根っこの発想はかなり近いです。

まずは「部品を渡す箱」で考える

DIコンテナとは、プログラムが必要とする部品を登録し、生成し、必要な場所へ渡してくれる仕組みです。DIという手法を実際の開発で扱いやすくしてくれます。

Springや.NETなどで呼び方や機能には違いがありますが、「使う側が自分で部品を作らなくてもよい」というところを押さえると、説明を読み進めやすくなります。

次にコードでDIという文字を見かけたら、「この部品は誰が作って、どこから渡されるんだろう?」と一度見てみてください。そこから追うと、DIコンテナの役割がかなり見つけやすくなりますよ。

情報は更新時点のものです。最新情報は公式サイトもあわせてご確認ください。

この記事を書いた人

「ゴイノワ」ナギ

『くらしごと』では、暮らしの中で気になることや、動く前にちょっと確認しておきたいことをわかりやすくまとめています。

注目記事

よかったらシェアしてね!
  • URLをコピーしました!
目次