Dev Study
← 解説「DIの考え方」に戻る

サンプルコードで身につける: DIの考え方

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1自分で new する場合と外から渡す場合

依存を自分で new するクラスと、外から受け取るクラスを並べた最小比較です。注入される側のコードは1文字も変えずにロガーを差し替えられる、という DI の利点が最小単位で分かります。

TypeScript

2契約(型)に依存して実装を選ぶ

利用側が具体的なクラス名ではなく「ログを書ける何か」という契約だけに依存する形です。開発中はコンソール、本番はファイル、のように組み立て時に実装を選べるのが、DI と相性の良い設計の核心です。

// 利用側は「ログを書ける何か」という契約(型)だけに依存する
type Logger = { log(message: string): void };

class ConsoleLogger {
  log(message: string): void {
    console.log(message);
  }
}
class FileLogger {
  log(message: string): void {
    /* ファイルに追記する処理 */
  }
}

class OrderService {
  constructor(private logger: Logger) {} // どちらが来ても動く
  placeOrder(): void {
    this.logger.log("注文を受け付けました");
  }
}
// 開発: new OrderService(new ConsoleLogger())
// 本番: new OrderService(new FileLogger())

3テストでの差し替え — 偽物のメール送信

DI の実務上いちばん大きな見返りであるテスト容易性の例です。本物のメール送信クラスを「記録するだけの偽物」に差し替えることで、メールを実際に送らずに送信内容を検証できます。

TypeScript

4依存グラフの手動組み立て

実務アプリで典型的な「コントローラ → サービス → リポジトリ → DB接続」という多段の依存を手動で組み立てた例です。末端から順に new する必要があり、この面倒さを自動化するのが DI コンテナの仕事だと分かります。

// 実務アプリの依存関係は多段になる
// OrdersController → OrdersService → OrderRepository → DbConnection
class DbConnection {}
class OrderRepository {
  constructor(private db: DbConnection) {}
}
class OrdersService {
  constructor(private repo: OrderRepository) {}
}
class OrdersController {
  constructor(private service: OrdersService) {}
}

// 手動だと末端から順に new する必要がある(依存が増えるほど悲惨)
const controller = new OrdersController(
  new OrdersService(new OrderRepository(new DbConnection())),
);
// この組み立て作業を肩代わりするのが DI コンテナ

5NestJSのコンテナが肩代わりすること

手動の組み立てと NestJS に任せた場合の対比を整理したまとめです。開発者の仕事は「欲しい型をコンストラクタに書く」ことだけになる、という次のレッスン以降の世界観を予告します。

// 前: 手動の組み立て(どこかに必ず new の山ができる)
// const controller = new OrdersController(
//   new OrdersService(new OrderRepository(new DbConnection())),
// );
//
// 後: NestJS の DI コンテナに任せた世界
//  - 登録 … クラスをコンテナに登録する(書き方は次のレッスン)
//  - 解決 … コンストラクタの型を見て必要な部品を自動で渡す
//  - 寿命 … 一度作ったインスタンスはアプリ全体で使い回す
//
// 開発者がやるのは
//   constructor(private service: OrdersService) {}
// と「欲しい型」を宣言することだけになる