第6章:DIPの定義をやさしく分解②(依存の逆転)🙃🔁
この章は DIPでいちばん「ん?逆転って何が?」ってなるところを、スッキリ言葉にできるようにする回だよ〜!🧠✨ (ちなみに今のC#は C# 14 が最新で、.NETは .NET 10 が現行の軸だよ🧡) (Microsoft Learn)
6.1 今日のゴール🎯✨
読み終わったら、これができるようになるよ👇😄
- 「何が逆転したのか」を 自分の言葉で説明できる🗣️✨
- 「逆転前/逆転後」を 矢印の図で描ける✍️➡️
- 「interfaceはどこに置く?」で迷った時に 判断できる🧭💡
6.2 まずは“逆転前”を1枚で見よう😵➡️🗄️
ありがちな形👇(業務ロジックがDB都合に引っ張られがち😢)
public class UserService
{
public void Register(string name)
{
var repo = new SqlUserRepository(); // ← ここがガチガチ依存💥
repo.Insert(name);
}
}
public class SqlUserRepository
{
public void Insert(string name)
{
// DBにINSERTする処理
}
}
この状態を「依存の矢印」で描くとこう👇
- 業務(上位) → DB実装(下位) 😵
UserService ─────▶ SqlUserRepository
(上位) (下位)
ここでつらいのがコレ👇😭
- DB種類が変わる、APIにしたい、保存先をファイルにしたい… → 上位のコードが直接巻き込まれる🌀
6.3 “逆転”って、何が逆になったの?🙃🔁(ここが本題!)

DIPの「逆転」は、ざっくり言うと 2つあるよ👇✨
①「契約(interface)を誰が持つか」が逆転する📜🔁
- 逆転前:下位(DB側)の都合で形が決まる🗄️
- 逆転後:上位(業務側)が「私これが欲しい」を決める🏰✨
イメージはこう🍽️💡
- 上位(業務)=お客さん「この注文票で頼みたい!」
- 下位(DB等)=厨房「了解、その注文票に合わせる!」
つまり “注文票(interface)”は上位が持つのが気持ちいい🎀
②「参照(プロジェクト参照 / 型参照)が逆転する」🔁📦
逆転前はこうだった👇
- 上位が下位の“具体クラス”を知ってる(=参照してる)😵
逆転後はこう👇
- 上位は 抽象(interface)だけ知ってる😍
- 下位が その抽象を実装して合わせにくる🛠️✨
ここがまさに 依存の矢印が逆転するポイントだよ〜!🧡
6.4 “逆転後”を図で見る😍⬅️➡️

ゴールの形👇✨
- 逆転後:業務 → interface ← DB実装 😍
UserService ─────▶ IUserRepository ◀───── SqlUserRepository
(上位) (抽象) (下位・詳細)
「え、矢印2本あるの?」ってなるけど大丈夫😊
- UserServiceは「約束(interface)」だけ見てる
- SqlUserRepositoryは「その約束を守る側」
6.5 コードで体験:逆転前 → 逆転後🔧✨
Step 1:上位側に“約束(interface)”を作る🤝💡
public interface IUserRepository
{
void Insert(string name);
}
ポイント💡:interfaceは“上位(業務)側の都合”で設計する🎀 (DBっぽい型を漏らしにくくなるよ!)
Step 2:上位(Service)は interface にだけ依存する🛡️✨
public class UserService
{
private readonly IUserRepository _repo;
public UserService(IUserRepository repo)
{
_repo = repo;
}
public void Register(string name)
{
_repo.Insert(name);
}
}
ここで起きた変化はこれ👇😄
new SqlUserRepository()が消えた🧹✨- Serviceの依存先が「具体」→「抽象」になった🎯
Step 3:下位(DB実装)は interface を実装して合わせにくる🗄️➡️🤝
public class SqlUserRepository : IUserRepository
{
public void Insert(string name)
{
// DBにINSERTする処理
}
}
はい、これで 「逆転」完成🎉✨ 上位が下位に合わせるんじゃなくて、下位が上位の決めた約束に合わせた🙃🔁
6.6 「逆転できてる?」チェックリスト✅🧭
やってみて、ここをチェックすると迷子になりにくいよ😊✨
-
上位(業務)のプロジェクトが、下位(DB/HTTP/ファイル)を参照してない?📦🚫
-
上位のコードに
new Sql...みたいな「下位の具体名」出てない?👀💥 -
interfaceのメソッド引数・戻り値に「DBっぽい型」が漏れてない?🗄️😵
- 例:
SqlConnectionとかDbDataReaderとかが業務側に出るのは黄色信号⚠️
- 例:
6.7 よくある罠💣(ここ踏みがち!)
罠①:interfaceを“下位プロジェクト側”に置いちゃう😇➡️😵
「RepositoryってDB側だよね?」って思って、Infrastructureに IUserRepository を置くと…
- 業務側がそのinterfaceを使うために 下位プロジェクト参照が必要
- つまり 依存が逆転してない(むしろ固定されやすい)🫠
interfaceは“上位が欲しい形”なので上位側に置くのが基本だよ🎀✨
罠②:interfaceがなんでも屋になる🐘💦
IUserRepository に「検索も更新も削除も集計も…」って詰め込みすぎると
結局 差し替えしにくい巨大な約束になって逆効果😢
コツは👇✨
- まずは「今回のユースケースに必要な最小」だけから始める🎯
6.8 章末ミニ演習📝🎮(30分でOK)
演習A:言葉にする練習🗣️✨
次の文を埋めてみてね👇(口に出すと強い!)
- 逆転前:上位(___)が下位(___)に依存していた😵
- 逆転後:上位(___)は抽象(___)に依存し、下位(___)がそれを実装した😍
演習B:差し替え体験🔁😄
SqlUserRepository の代わりに、メモリ版を作って差し替えてみよう👇
public class InMemoryUserRepository : IUserRepository
{
private readonly List<string> _users = new();
public void Insert(string name)
{
_users.Add(name);
}
}
できたら「差し替えでService側が一切変わらない」快感を味わって〜!🎉💕
6.9 🤖AI(Copilot / Codex)で理解を爆速にするプロンプト例⚡
そのまま貼って使えるよ〜😄💡
- 「このコードの依存の矢印を図で説明して。逆転前/逆転後も描いて」🧭
- 「DIP的に、interfaceはどこに置くべき?理由もセットで」📦
- 「この
newが散らばったコードを、最小のDIPでリファクタして。手順も」🧹✨ - 「業務側にDB型が漏れてるかチェックして、漏れてたら改善案」🗄️🚫
まとめ✨🎀
- DIPの“逆転”は 実行順が逆とかじゃなくて、 依存(参照)と契約(interfaceの持ち主)が逆ってこと🙃🔁
- 上位(業務)が「欲しい形(interface)」を決める🏰
- 下位(DB等)が「それを実装して合わせる」🛠️
- 結果:上位が守られて、差し替えが楽になる😍✨
(今の最新環境だと .NET 10 / C# 14 / Visual Studio 2026 あたりが中心だよ📌) (Microsoft Learn) (.NETにはDIの仕組みも標準で揃ってるので、あとで“つなぎ方”も自然に学べるよ🤖🔧) (Microsoft Learn)