第7章 IoCの本体:主導権が逆になるってどういうこと?🌀
この章は、「DIって便利そうだけど…IoCって何?」を“ふわっと”じゃなく、手触りでわかるようにする回だよ😊✨ (ここが腑に落ちると、DIの理解が一気に楽になるよ〜!)
1) 今日のゴール🎯🌸
章末までに、これができたら勝ち🏆✨
- IoC = 主導権(コントロール)が逆になるって言葉で説明できる🗣️🌀
- 「自分で取りに行く設計」と「外から渡される設計」の違いを見抜ける👀
- IoCの代表例として DI(依存性注入) を“位置づけ”できる💉
- 「IoCっぽいのに事故るコード」の匂いを嗅げる🐶💦
IoCはフレームワークの特徴として語られることが多く、DIはその具体例のひとつ…という関係だよ📚✨ (martinfowler.com)
2) IoCって一言でいうと?🌀✨
✅ IoC(Inversion of Control)=「呼び出しの主導権が、アプリから“外側”へ移る」こと
イメージはこれ👇
- ふつうのプログラム:自分のコードが、必要なものを呼び出して進める
- IoCな世界:外側(フレームワーク/ランタイム/起動コード)が、あなたのコードを呼び出す
Martin Fowlerも「IoCはフレームワークを拡張するときに頻出する特徴」って説明してるよ📌 (martinfowler.com)
3) まず“超わかりやすいIoC”から:イベント🖱️🎉

IoCって、実はDIより前にもう体験してる人が多いよ😊
たとえばボタン押下(イベント)ってこう👇
- あなた:
button.Click += ...って登録する - その後:あなたはClickを呼ばない
- 代わりに:UIフレームワークが「押されたよ!」ってあなたの処理を呼ぶ
これがまさに “Don't call us, we'll call you”(呼ぶのはそっち)ってやつ🌀 IoCは「Hollywood Principle」って説明されることもあるよ🎬 (ウィキペディア)
4) じゃあDIはIoCとどう関係するの?💉🌀
✅ DIは「IoCを実現する代表的なやり方のひとつ」だよ
Martin Fowlerの解説では、軽量コンテナがやってる“配線(wiring)”の思想を IoC と呼び、そこでの具体的なやり方として DI を掘り下げてるよ📌 (martinfowler.com)
5) “主導権が逆”をコードで体感しよう👀✨(ミニ比較)
題材:時刻を使う処理(ありがち!)⏰
❌ IoCじゃない側(自分で取りに行く)
public sealed class GreetingService
{
public string BuildMessage()
{
// 自分で取りに行く(主導権がクラス側)
var now = DateTime.Now;
return now.Hour < 12 ? "おはよう☀️" : "こんにちは🌤️";
}
}
DateTime.Nowは外界(時刻)=I/Oっぽい依存- テストしたい時に「朝のケース」「午後のケース」を作りにくい😵💫
✅ IoCな側(外から渡される:DIの形で)
public interface IClock
{
DateTime Now { get; }
}
public sealed class SystemClock : IClock
{
public DateTime Now => DateTime.Now;
}
public sealed class GreetingService
{
private readonly IClock _clock;
// 外から渡される(主導権が外側へ移る)
public GreetingService(IClock clock) => _clock = clock;
public string BuildMessage()
{
var now = _clock.Now;
return now.Hour < 12 ? "おはよう☀️" : "こんにちは🌤️";
}
}
ここで起きてること🌀✨
GreetingServiceは「時計を取りに行かない」- 代わりに「時計を渡される」
- 組み立て(どの時計を使うか)の主導権は外側へ📦
これが “IoCの感覚” だよ😊💕
6) “外側で組み立てる”ってどこ?📍(Composition Rootの予告)
今はまだ第13章で本格的にやるけど、先に雰囲気だけ!
// Program.cs(外側:起動する側)
IClock clock = new SystemClock();
var service = new GreetingService(clock);
Console.WriteLine(service.BuildMessage());
- アプリの「入口側(起動側)」が組み立てて
- 中心ロジックは「渡されたものを使うだけ」✨
この「入口でまとめて組み立てる」思想は、.NETのDIでも基本は同じだよ(IServiceCollection/IServiceProvider など)📌 (Microsoft Learn)
7) ミニ演習🧪✨(10〜20分)
演習A:Before→Afterで“主導権逆転”を体感🌀
GreetingServiceの中にDateTime.Nowがある版を作るIClockを作って、SystemClockを実装- コンストラクタで
IClockを受け取る形に直す Program.csで組み立てる
🌟チェック:GreetingService の中から new が減った?
🌟チェック:依存が 引数に見える形になった?
演習B:Fakeでテストできる喜び💖
public sealed class FakeClock : IClock
{
public DateTime Now { get; set; }
}
FakeClock.Nowを朝にして「おはよう」を確認- 午後にして「こんにちは」を確認
この“差し替えの気持ちよさ”がDIのご褒美だよ🍰✨
8) よくある勘違い&つまずきポイント🥺🧯
❗勘違い1:IoC=DIコンテナのこと?
ちがうよ〜!🙅♀️ IoCはもっと広い概念で、イベントもフレームワークもIoC。DIはその中の有名な手段のひとつだよ📌 (martinfowler.com)
❗勘違い2:「渡される」って、結局どこかでnewしてるじゃん?
うん、してる!😊 でも大事なのは「中心ロジックの中でnewしない」こと。 “組み立て”を外に追い出すと、変更やテストが楽になるよ✨
9) AI(Copilot/Codex等)に頼ると超早い🤖💨
そのままコピペで使えるプロンプト例だよ🌸
- 「このクラスの隠れた依存(new / DateTime.Now / Console / HTTPなど)を列挙して、DI向けに分離案を出して」
- 「このコードをコンストラクタ注入に直して。インターフェースも作って」
- 「Fake実装を作って、朝/昼のテストケースを2本作って」
- 「この設計で“主導権がどこにあるか”を図(箇条書き)で説明して」
10) 章末ミニクイズ🎯✨(答えつき)
Q1. IoCの超ざっくり説明として正しいのは? A. 依存を全部interfaceにすること B. 呼び出しの主導権が外側に移ること C. newを禁止すること
✅答え:B 🌀
Q2. イベントハンドラはIoC? ✅答え:Yes(自分が呼ぶんじゃなくて、フレームワークが呼ぶから) (ウィキペディア)
Q3. DIはIoCの…? ✅答え:IoCを実現する代表的な手段のひとつ (martinfowler.com)
まとめ🍀✨
- IoCは「主導権が逆になる」こと🌀
- その“逆転”をコードで作る代表手段がDI💉
- 中心ロジックは「取りに行かず、渡されて使う」だけにすると強い💪✨
- 次の章(第8章)で、いよいよ コンストラクタ注入(最重要)🥇 を固めて、DIを“型”にするよ〜😊🎉
続けて「第7章の内容を、演習付きの1ファイル完結サンプル(Console)にして」みたいに言ってくれたら、そのままコピペで動く教材コードも作るよ💖