ソフトウェア設計

依存性の注入(DI) いぞんせいのちゅうにゅう

DI依存性の注入IoC疎結合テスタビリティDIコンテナ
依存性の注入って何のためにやるの?

簡単に言うとこんな感じ!

DIは「部品が自分で依存するものを作るんじゃなく、外から渡してもらう」設計のことだよ!コーヒーメーカーが自分でコーヒー豆を育てるんじゃなく、外から豆を「注入」してもらう感じ。これでテストするとき「本物のDB」の代わりにモックを注入できて、ユニットテストが楽になるんだ。


依存性の注入(DI)とは

依存性の注入(DI:Dependency Injection) とは、クラスが依存するオブジェクト(サービス・DB・API等)をクラス内部で生成せず、外部から「注入(Inject)」する設計パターンです。

「制御の逆転(IoC:Inversion of Control)」の実装方式のひとつです。クラスが自分の依存関係を制御するのではなく、外部の「DIコンテナ」や呼び出し元が制御します。


DIの種類

種類内容
コンストラクタ注入コンストラクタの引数で渡す最も推奨される方式
セッター注入setterメソッドで渡す任意の依存関係に使用
フィールド注入フィールドに直接注入(アノテーション等)Spring・JavaEEで多用

DIのメリット

// DIなしの場合(密結合)
class OrderService {
  private db = new PostgreSQLDatabase(); // 直接生成。テストで変えられない
  createOrder(order: Order) { ... }
}

// DIありの場合(疎結合)
class OrderService {
  constructor(private db: IDatabase) {} // 外から注入。テスト時はモックDBを渡せる
  createOrder(order: Order) { ... }
}

主なDIコンテナ・フレームワーク

フレームワーク言語
Spring(DI Container)Java
NestJS(IoC)TypeScript
.NET Core DIC#
Dagger / HiltAndroid(Java/Kotlin)
tsyringeTypeScript

歴史と背景

  • 2000年代前半Spring FrameworkのDIコンテナが普及の火付け役
  • 2004年:Martin FowlerがDIを「Inversion of Control Containers and the Dependency Injection pattern」で定義
  • 現在:フレームワークが自動でDIを管理するため意識しにくくなっている

関連用語