メインコンテンツまでスキップ

依存性注入(DI)/IoC:30章アウトライン(C# / 2026 / Windows)💉🧩🪟

C#初級〜中級/設計は超入門/Windows+Visual Studio中心/AI拡張あり🤖


全体のゴール(この教材でできるようになること)🎯

  • 「なぜDIが必要か」を怖くない言葉で説明できる😊
  • コンストラクタ注入で、差し替え可能な設計にできる💉
  • Composition Root(組み立て場所)を作って、依存を散らさない📍
  • 必要になったら DIコンテナを安全に導入できる🧰
  • DIのおかげで テストが簡単になるのを体感できる🧪✨

30章アウトライン(詳細)🌷

第1章 はじめに:DIって結局なにが嬉しいの?🌈

  • ゴール:DIの“ごほうび”がイメージできる😊

  • 内容:変更が怖くない/テストしやすい/差し替えできる

  • ミニ演習:日常例(スマホ充電器・イヤホン等)で「差し替え」を言語化🔌

  • AI活用🤖:

    • 「DIのメリットを中学生に説明して」みたいに言い換え練習✨

第2章 “依存”ってなに?まず言葉を怖くなくする🧩

  • ゴール:「依存=それがないと困る相手」が言える
  • 内容:依存の例(時計・ログ・HTTP・DB)⏰🧾🌐🗄️
  • ミニ課題:自分の過去コードから「依存っぽいもの」3つ探す🔎
  • AI活用🤖:コード貼って「依存を列挙して」✨

第3章 失敗例:newだらけコードの“つらさ”を体験😵

  • ゴール:「なぜ困るのか」を体感する
  • 内容:差し替え不可/テストしにくい/変更が連鎖
  • 演習:new直書きの小コードを読む📖
  • つまずき:まだDIの解決策を急がない(ここは“困る”の確認だけ)🧘

第4章 SoCの入口:混ぜると壊れる、分けると楽になる🍱

  • ゴール:関心(ロジック vs I/O)を分ける感覚をつかむ
  • 内容:I/O(外部)と純粋ロジック(内部)🌟
  • 演習:ロジックとI/Oに色分け(コメントでOK)🎨
  • AI活用🤖:「このコード、I/Oとロジックに分ける案を出して」

第5章 インターフェース超入門:差し替え口を作ろう🧷

  • ゴール:interface=“取り替え可能な口”だと理解する
  • 内容:具体→抽象へ(クラスを直接持たない)
  • 演習:ILoggerっぽい最小interfaceを作る🧾
  • ミニ課題:実装を2つ作って差し替える(Console版/ダミー版)🔁

第6章 DIの本体:外から渡す(注入)ってこれ!💉

  • ゴール:DI=「外から渡す」だけ、と言える
  • 内容:newの場所を“外”へ追い出す
  • 演習:コンストラクタ引数で依存を受け取る
  • AI活用🤖:既存コードを貼って「DI化する手順を出して」

第7章 IoCの本体:主導権が逆になるってどういうこと?🌀

  • ゴール:IoC=“呼び出し側が組み立てる”感覚
  • 内容:「自分で取りに行く」→「渡される」へ
  • 演習:依存を自分でnewする版 vs 外から渡される版を比較👀

第8章 コンストラクタ注入(最重要):まずはこれだけでOK🥇

  • ゴール:基本はコンストラクタ注入で十分と言える
  • 内容:必須依存はコンストラクタで固定📌
  • 演習:必須依存をコンストラクタへ移動
  • 章末チェック✅:「依存が引数に見えてる?」を見る

第9章 手を動かす①:Consoleアプリで“DI前→DI後”を体感⌨️✨

  • ゴール:DIの効果(差し替え)が気持ちよく分かる

  • 内容:小さなユースケース(通知/ログ/時刻)

  • 演習:

    • Before:クラス内new
    • After:外から注入
  • ミニ課題:ダミー実装を差し替えて動作確認🔁

第10章 メソッド注入:一時的に必要な依存だけ渡す🧤

  • ゴール:使いどころが分かる
  • 内容:1回限り/処理ごとに違う依存
  • 演習:Export時だけ必要なFormatterを引数で渡す📄
  • 注意⚠️:必須依存はコンストラクタへ戻す

第11章 プロパティ注入:便利そうに見えるけど落とし穴も🕳️

  • ゴール:プロパティ注入のリスクを理解
  • 内容:nullになりやすい/必須が見えにくい
  • 演習:わざとnull事故を起こして学ぶ🙈
  • 章末まとめ:基本は「必須=コンストラクタ」💡

第12章 DIとDIPの関係:似てるけど別物だよ🤝

  • ゴール:混同しない(超大事!)

  • 内容:

    • DIP=方針(上位)が詳細(下位)に引きずられない
    • DI=差し替えのための“やり方”
  • ミニ課題:どっちの話?クイズ5問🎯

  • AI活用🤖:クイズ自動生成してもらう

第13章 Composition Root:組み立て場所を1か所に集める📍

  • ゴール:依存を散らさない設計ができる
  • 内容:Main/Startupで組み立てる(手動DI)
  • 演習:Composition Rootを作ってnewをそこへ移動🚚
  • チェック✅:「newはどこにあるべき?」を言える

第14章 手を動かす②:手動DIを“きれいに”保つコツ🧹

  • ゴール:手動DIでも十分戦えると分かる
  • 内容:Factory化/引数地獄の避け方(小分け)🍰
  • 演習:組み立てをメソッドに分割して読みやすく
  • ミニ課題:依存が増えても読める構造にする📚

第15章 DIコンテナはいつ必要?YAGNIで判断しよう🧰

  • ゴール:導入の判断基準を持つ
  • 内容:手動がつらくなってからでOK👍
  • 目安:依存が増えた/組み立てが複雑/差し替えが多い
  • AI活用🤖:「この規模でコンテナ必要?」相談テンプレ作成

第16章 DIコンテナ入門:Microsoftの標準的なやつを使う🧩

  • ゴール:最小導入ができる
  • 内容:Microsoft.Extensions.DependencyInjection の雰囲気
  • 演習:ServiceCollection→BuildServiceProviderまで
  • 注意⚠️:ここでは“深追いしない”(触るだけ)👣

第17章 登録の基本:AddTransient / AddSingleton / AddScoped を覚える📝

  • ゴール:3種類の“名前”と意味の方向性をつかむ
  • 内容:登録=「こう作ってね」のルール
  • 演習:ILoggerを登録して解決(resolve)して使う🧾
  • つまずき:いきなり完璧理解しなくてOK🙆‍♀️

第18章 解決(Resolve)の基本:どこで取り出すの?🎣

  • ゴール:Resolveの置き場所を間違えない
  • 内容:Resolveは基本“外側”(Composition Root)で
  • 演習:起動時に解決して実行する流れを作る▶️
  • 注意⚠️:クラス内でServiceProvider使い始めると危険🚫

第19章 ライフタイム①:Transient(毎回新品)🧼

  • ゴール:いつ使うか分かる
  • 内容:状態を持たない軽いサービス向き
  • 演習:呼ぶたびに別インスタンスになるのを確認🔁
  • ミニ課題:Transient向き/不向きを分類🗂️

第20章 ライフタイム②:Singleton(1個共有)👑

  • ゴール:便利だけど注意が必要と分かる
  • 内容:共有=状態管理が難しい(スレッド注意)⚠️
  • 演習:Singletonの共有挙動を確認👀
  • 章末ルール:基本は“状態を持たせない”方向へ🌿

第21章 ライフタイム③:Scoped(範囲内で共有)🧺

  • ゴール:Webでのイメージがつく
  • 内容:「1リクエスト内で共有」っぽい感じ🌐
  • 演習:Scopeを作って挙動確認(Consoleでもできる)🧪
  • つまずき:Scopeは“境界”の話、と覚える

第22章 設定(Options)をDIで扱う:ハードコード卒業🎛️

  • ゴール:設定値を安全に渡せる
  • 内容:設定クラス/読み込み/注入
  • 演習:App設定→Optionsクラス→注入
  • ミニ課題:環境別(開発/本番)を想定して分ける🌍

第23章 ログをDIで扱う:ILoggerの気持ち良さ🧾✨

  • ゴール:ログを“依存”として扱える
  • 内容:ログは外部I/O寄り=差し替え価値が高い
  • 演習:ILoggerを注入してログ出力
  • 章末課題:ログ出力をテストで確認(ダミー実装)🧪

第24章 HTTPをDIで扱う:外部APIとの付き合い方🌐

  • ゴール:外部通信も差し替え前提で設計できる
  • 内容:Clientのinterface化/アダプタ化
  • 演習:外部APIクライアントをinterfaceで包む🧷
  • 注意⚠️:I/Oは“薄い層”に押し出す(SoC)🍱

第25章 テストの入口:DIがあるとテストがラクになる🧪💖

  • ゴール:DIとテストの相性を体感
  • 内容:Fake/Stubの差し替え
  • 演習:時計(IClock)をFakeにしてテストする⏰
  • ミニ課題:3パターンのテストケースを書く✍️

第26章 モック入門:呼ばれ方を確かめる(相互作用テスト)🕵️‍♀️

  • ゴール:モックの“何が嬉しいか”が分かる
  • 内容:呼び出し回数/引数/順番を確認
  • 演習:通知サービスが「1回だけ呼ばれた」を検証✅
  • 注意⚠️:モックは乱用しない(大事な所だけ)🌿

第27章 アンチパターン①:Service Locatorがダメな理由🚫

  • ゴール:「DIっぽいけどDIじゃない」を避ける
  • 内容:依存が見えない/テストしにくい
  • 演習:Service Locator版→正しい注入版へ修正🔧
  • 章末ルール:依存は“引数で見せる”👀

第28章 アンチパターン②:循環参照をほどくコツ🌀

  • ゴール:A→B→Aの詰みを解消できる
  • 内容:責務分割/中間抽象/イベント化(軽く)
  • 演習:循環例を作って、分割で直す🧩
  • AI活用🤖:「循環の原因候補を出して」診断プロンプト

第29章 設計の健康診断:巨大コンストラクタはSOSサイン📣

  • ゴール:依存が多すぎる時の見直し方が分かる
  • 内容:SRP/SoCに戻る/小さなサービスへ分割
  • 演習:引数8個のクラスを分割して3個にする✂️
  • チェック✅:「これは責務過多?」判断クイズ

第30章 総合演習:ミニアプリをDIで仕上げる🎀🏁

  • ゴール:DIの流れを最初から最後まで自力で通す

  • 題材例:

    • 「簡易家計メモ」or「ToDo」or「学習記録」📒✅
    • 依存は最大3つ(時計/ログ/外部API)に抑える🙂
  • やること:

    1. interface設計
    2. コンストラクタ注入
    3. Composition Root 4)(余裕あれば)コンテナ導入
    4. テスト1〜3本🧪
  • AI活用🤖:

    • 仕様→クラス候補→依存図→実装ひな形、の順で安全に使う✨
  • 最終チェックリスト✅:

    • 「newが中心ロジックに残ってない?」
    • 「依存が引数で見えてる?」
    • 「差し替えでテストできた?」