第30章 DI入門①:DIって何?なぜ必要?🧠🔧✨
カフェ注文アプリ☕で、最初は InMemory で動いたけど… 「よし!次はDBにしたい!」ってなった瞬間に、変更が一気に怖くなることあるよね😵💫💥
そこで登場するのが DI(Dependency Injection / 依存性注入) だよ〜!🎉
1) DIを一言でいうと?🧩✨

「部品(依存先)を、自分の中でnewして作らず、外から渡してもらう」 ってことだよ😊🔌
- ❌ 自分で部品を買いに行く(中で
newする) - ✅ 受付で部品を受け取る(外から渡される=注入)
ASP.NET Core / .NET は “最初からDIを前提に作られてる” ので、自然にDIを使う流れになってるよ🧡 (公式ドキュメントでも、ASP.NET Core が DI パターンをサポートしていることが明記されてるよ) (Microsoft Learn)
2) なんでDIが必要なの?「new地獄」から抜けるため😇🔥
🔥 ありがちな地獄(DIなし)
たとえば UseCase の中で、こうやって作っちゃう👇
public class CreateOrderUseCase
{
public void Handle(CreateOrderCommand command)
{
// ❌ ここで具体実装を new しちゃう
var repo = new InMemoryOrderRepository();
repo.Save(/* ... */);
}
}
この瞬間に、UseCaseが 「InMemoryを知ってしまう」 のが痛い😭💔 DBに変えたい時、UseCaseを書き換える羽目になる…!
しかもテストもつらい😵
- DBが必要?
- インメモリ固定?
- 置き換え不可?
3) DIがくれる“うれしさ”3点セット🎁✨
✅ ① 差し替えが楽(InMemory ↔ DB)🔁🗃️
Core は「保存できればOK」だけ知っていればいい。 どの保存方法かは外側の都合 にできるよ😊
✅ ② テストが爆速で書ける🧪💖
Fake(偽物)を注入して、DBなしでUseCaseを検証できる! 「テストのために環境作る」が減るの最高😆✨
✅ ③ 依存の向きがキレイになる🧼➡️🛡️
ヘキサの目的そのもの! CoreはPort(interface)だけ見て、Adapterは外で差し替え ができる💪
4) ヘキサ視点でのDI:DIは“配線係”だよ🔌🧩
思い出してね👇
- Port = 「こうしてね」の約束(interface)📝
- Adapter = 約束を満たす実装(InMemory/DB/外部API)🔧
- DI = Port と Adapter をつなぐ“配線” 🧩✨
つまりこう!👇
「Coreのコードは変えずに、外側の配線だけ変える」 🥳🔁
.NETのDIの基本は Microsoft の公式ドキュメントにもまとまってるよ(DIの概念、依存グラフ、注入の考え方など) (Microsoft Learn)
5) DIの基本形は「コンストラクタ注入」🏗️💉
一番スタンダードで、設計がキレイになりやすいのがこれ😊
✅ Port(Core側)
public interface IOrderRepository
{
void Save(Order order);
}
✅ UseCase(Core側):interface を受け取る
public class CreateOrderUseCase
{
private readonly IOrderRepository _repo;
// ✅ ここで受け取る(注入)
public CreateOrderUseCase(IOrderRepository repo)
{
_repo = repo;
}
public void Handle(CreateOrderCommand command)
{
var order = Order.Create(/* ... */);
_repo.Save(order);
}
}
この瞬間に、UseCaseはこう思ってるだけになる👇 「保存できる人(IOrderRepository)ちょうだい🥺」 InMemoryかDBかは知らない!最高!😆✨
6) 「じゃあ誰が注入するの?」→ それは外側(配線場所)📍🧩
ここが超重要ポイントだよ〜!📌💕
- Core(UseCase/Domain)は 注入される側
- 外側(起動時の場所)は 注入する側(配線する側)
ASP.NET Core だと、アプリ起動時にDIコンテナへ登録して、必要な時に自動で注入される仕組みが標準で用意されてるよ (Microsoft Learn)
※登録(AddScoped とか)や Program.cs の具体は 次章(第31章) でガッツリやるよ🔧✨
7) DIでありがちな勘違いあるある😵💫💦
❌ 「DI = new禁止」ではないよ!
正しくはこう👇 「newする場所を、ちゃんと“外側の1か所”に寄せようね」 🧹✨
Coreの中でnewしまくるのが問題で、 外側(配線)でnewするのは普通にアリだよ😊(ただし .NET ではコンテナに任せるのが一般的)
8) DIを導入する“超実践ステップ”🪜✨
カフェ注文アプリ☕でやるなら、こう進めると安全だよ😊
- 「外とつながる処理」を探す(DB保存、メール送信、時刻取得…)🔍
- それを Port(interface)にする 📝
- Coreは interfaceをコンストラクタで受け取る 💉
- 実装(Adapter)は外側に置く 🔧
- 最後に外側で 配線する 🔌🧩(次章で!)
9) ミニ演習(10分)⏱️🧪✨
演習A:newを追い出そう🏃♀️💨
- UseCase内に
new InMemoryOrderRepository()があったら削除! IOrderRepositoryをコンストラクタで受け取る形に直す!
演習B:Fakeでテスト気分💖
FakeOrderRepository : IOrderRepositoryを作る- UseCaseに注入して、
Saveが呼ばれたかを確認してみよう😆
10) AI(Copilot/Codex)に手伝ってもらうコツ🤖✨
DIは“型と置き場所”が大事だから、AIに頼む時は指示をハッキリめにすると強いよ💪
おすすめプロンプト例👇(そのままコピペOK🫶)
- 「このクラスの依存を constructor injection に直して。
newをクラス内部から消して、interface経由にして」 - 「Hexagonalの前提で、CoreがAdapter実装を参照しないようにリファクタして」
- 「
IOrderRepositoryのFake実装を作って、UseCaseの単体テスト例も出して」
まとめ:第30章で持ち帰ること🎒✨
- DIは 「依存を外から渡す」 こと🧩
- DIの価値は 差し替え・テスト・依存方向 を一気にラクにするところ🎁
- ヘキサでは DI は PortとAdapterをつなぐ配線 🔌✨
- .NET / ASP.NET Core は DI が標準機能として組み込まれてるよ (Microsoft Learn)
次の第31章では、いよいよ .NET のDI登録(AddScopedとか) を触って、「自動で注入される気持ちよさ」 を体験するよ〜😆🔧💖