第17章:サイト用「共通リソース集」🧰🌸
この章は、教材のどの章から来ても迷子にならないための「辞書📖+テンプレ📦+AIプロンプト集🤖」です✨ 必要なところだけコピペして使ってね😊
17-1. 開発環境まとめ🪟🛠️
まずは“いまの最新版”だけ押さえる🎯
- .NET(最新LTS):.NET 10.0(最新リリース 10.0.1 / 2025-12-09) (Microsoft)
- C#(最新):C# 14(.NET 10でサポート) (Microsoft Learn)
- Visual Studio 2022(安定運用枠):Current 17.14.23(2025-12-16) (Microsoft Learn)
- (試したい人向け)Visual Studio 2026 Insiders:.NET 10向けの“次世代VS”を先取りできる枠 (Visual Studio)
バージョン確認コマンド🔎(困ったらまずコレ)
dotnet --info
Copilot(Visual Studio内)関連の“覚えておくと強い”ポイント🤖✨
- Visual Studio では Copilot Chat が IDE に統合されていて、チャット/インライン両方で使い分けできるよ💬✍️ (Microsoft Learn)
- Visual Studio 右上に Copilotの状態アイコン(有効/無効/未インストール等)が出るので、迷ったらそこを見る👀 (Microsoft Learn)
- VS 2026 Insiders では Copilotで単体テストを生成&実行みたいな機能も案内されてる🧪 (Microsoft Learn)
17-2. 用語集📖✨(この教材で使うやつだけ)
“ふわっと”でOK👌 でも、言葉が揃うと設計が一気に楽になるよ😊
- 関心(Concern):そのコードが気にしていること(例:表示、割引ルール、DB保存…)
- SoC(関心の分離):関心を混ぜない🧁➡️🍱(混ぜると修正が爆発する💥)
- 責務(Responsibility):そのクラスが「何を担当するか」
- 変更理由:そのコードが変わる理由(責務を見つける最強ヒント🔦)
- 境界(Boundary):ここから先は別世界!の線引き(UI ↔ 業務 ↔ DB/外部)🧱
- 依存(Dependency):「AがBを知ってる/使ってる」状態
- 依存の向き:守りたい中心(業務)に、外側(DB/UI)を持ち込まない向き🧲
- DIP:依存の向きを整える考え方(“抽象に依存”がキーワード)
- DI:依存を
newで作らず外から渡す💉(差し替えしやすい!) - I/O(入出力):DB、ファイル、HTTP、時計、乱数など“外界”要素🌍
- Entity:業務ルールの中心にいるデータ(状態とルールを持てる)
- DTO:外に出す/外から来るための入れ物📦(API/DB/ファイル等)
- ViewModel:画面都合の入れ物🖥️(表示用の形)
- Repository:保存/取得の窓口🚪(業務からDB都合を隠す)
- UseCase(Application):画面から呼ばれる“やりたいこと”の手順書🧠🗺️
- Mapper(Mapping):DTO/Entity/ViewModel を詰め替える係🔄
- 単体テスト:小さい単位で正しさを確認🧪
- AAA:Arrange(準備)→ Act(実行)→ Assert(確認)✅
17-3. テンプレ集📦✨(コピペして使えるやつ)

17-3-1. フォルダ構成例(最小で“4分離”)🗂️
「分ける=正義」じゃなくて、迷わない最小セットが大事😊
/MyApp
/src
/MyApp.UI ← 画面(WinForms/WPF)
/MyApp.Application ← UseCase(手順)
/MyApp.Domain ← ルール(Entityなど)
/MyApp.Infrastructure ← DB/HTTP/ファイルなど
/tests
/MyApp.Application.Tests
/MyApp.Domain.Tests
17-3-2. 命名テンプレ(迷ったらこの型)🏷️
- interface:
I〇〇Repository/I〇〇Client/I〇〇Gateway - 実装:
Sql〇〇Repository/Http〇〇Client/File〇〇Store - 手順(UseCase):
〇〇UseCase(例:RegisterOrderUseCase) - 画面用:
〇〇ViewModel - 変換:
〇〇Mapperもしくは〇〇MappingExtensions
17-3-3. Repository 最小形(“保存係”を外に出す)🗄️🚪
// Domain/Application 側(=中心側)
public interface ICustomerRepository
{
Task<Customer?> FindByIdAsync(CustomerId id, CancellationToken ct);
Task SaveAsync(Customer customer, CancellationToken ct);
}
// Infrastructure 側(=外側)
public sealed class SqlCustomerRepository : ICustomerRepository
{
public Task<Customer?> FindByIdAsync(CustomerId id, CancellationToken ct)
{
// ここにSQL/ORMの都合を閉じ込める🧱
throw new NotImplementedException();
}
public Task SaveAsync(Customer customer, CancellationToken ct)
{
throw new NotImplementedException();
}
}
17-3-4. UseCase 雛形(UIは“これを呼ぶだけ”にする)📨✨
public sealed class RegisterCustomerUseCase
{
private readonly ICustomerRepository _repo;
public RegisterCustomerUseCase(ICustomerRepository repo)
{
_repo = repo;
}
public async Task ExecuteAsync(RegisterCustomerRequest request, CancellationToken ct)
{
// 1) 入力チェック(必要最低限)
if (string.IsNullOrWhiteSpace(request.Name))
throw new ArgumentException("Name is required.");
// 2) ルール(Domain)へ寄せる
var customer = Customer.Register(request.Name);
// 3) 保存(I/Oはrepoに丸投げ)
await _repo.SaveAsync(customer, ct);
}
}
public sealed record RegisterCustomerRequest(string Name);
17-3-5. DTO / Entity / ViewModel の詰め替えテンプレ🔄📦
「めんどいけど保険」=混ざらない未来を買う感じ😊
public sealed record CustomerDto(string Id, string Name);
public static class CustomerMappingExtensions
{
public static CustomerDto ToDto(this Customer entity)
=> new(entity.Id.Value, entity.Name.Value);
public static Customer ToEntity(this CustomerDto dto)
=> new(new CustomerId(dto.Id), new CustomerName(dto.Name));
}
17-3-6. テスト雛形(AAA:Arrange-Act-Assert)🧪✅
using Xunit;
public sealed class DiscountCalculatorTests
{
[Fact]
public void Gold_gets_10_percent_off()
{
// Arrange
var calc = new DiscountCalculator();
// Act
var actual = calc.Apply(1000m, MemberRank.Gold);
// Assert
Assert.Equal(900m, actual);
}
}
public enum MemberRank { Normal, Gold }
public sealed class DiscountCalculator
{
public decimal Apply(decimal price, MemberRank rank)
=> rank == MemberRank.Gold ? price * 0.9m : price;
}
17-4. AIプロンプト集🤖✨(章をまたいで使える“共通呪文”)
17-4-1. “分離ポイント発見”プロンプト🔍🧠
- 「このクラスの関心(UI/業務/I/O)を仕分けして、混ざってる箇所に印をつけて」
- 「このメソッドの責務を1文で。変更理由を3つ挙げて」
- 「SoC的に分けるなら、最初の1手(安全な小リファクタ)を3案ください」
17-4-2. “一気に直さない”プロンプト(段階プラン)🪜🌱
- 「動作を変えずに、①メソッド抽出→②クラス抽出→③interface化 の順で、手順を書いて」
- 「まずテストが書ける状態にしたい。I/O境界を外に追い出す作戦を提案して」
17-4-3. “小さな差分で出して”プロンプト✂️📌
- 「変更は最小で。差分(before/after)だけ提示して」
- 「UIイベントハンドラを痩せさせたい。
UseCase呼び出しだけ残して」
17-4-4. テスト生成(/tests など)🧪🤖
Copilot Chat には スラッシュコマンドがあって、例えば /tests で既存コードのテストを書かせる系の流れがあるよ✨ (GitHub Docs)
- 「
/testsこのクラスの主要分岐をカバーするテストを書いて(例外ケースも)」 - 「テストが落ちた理由を説明して、修正案を“最小差分”で出して」
17-4-5. Visual Studio の Copilot Chat を賢くする小技💬🧠
- チャット/インラインの使い分け(“コードを直接直したい”ならインラインが便利) (Microsoft Learn)
- カスタム指示(Custom instructions) で、チームの方針や前提を自動で付与できる系の説明もあるよ📎 (Microsoft Learn)
17-4-6. Codex(OpenAI)を使う時の“お願いテンプレ”🧑🍳🤖
- 「目的:〇〇。制約:破壊的変更NG。段階:小さく。最終的にPR説明文も作って」
- 「変更は3コミットに分けて:①テスト追加 ②リファクタ ③整理(命名/コメント)」
Codex の位置づけやアップデート情報は OpenAI 公式の案内を参照できるよ📌 (OpenAI)
17-5. よくある詰まりQ&A😵💫➡️😄
Q1. 「分けすぎた…クラス増えすぎた…」📦📦📦
A. あるある!😂 まずは “UI / UseCase / I/O” の3分離まで戻してOK。 「DTO/Mapperまで毎回作る」みたいなやりすぎは、外部連携が増えてからでも大丈夫😊
Q2. 「DTOとEntityがほぼ同じで意味ある?」🪞
A. 今は同じでもOKだよ👍 でも将来「画面に項目追加」「DB都合が増える」ってなった時、混ざってないのが効いてくる✨
Q3. 「Repositoryのメソッドが増殖する」🧟♀️
A. そのときは
- “用途ごと”にRepositoryを分ける(読み取り専用/書き込み専用)
- “検索条件”をオブジェクト化する(例:
CustomerQuery) みたいな整理が効くよ🧹✨
Q4. 「テストが面倒で進まない」🧪💦
A. 最初は “純粋ロジックだけ” でOK! 割引、状態遷移、入力チェック…みたいに I/Oが絡まない中心から書くと気持ちいい😊
Q5. 「Copilotの提案がデカすぎて怖い」😇
A. プロンプトをこう変えると安定するよ👇
- 「変更は最小」「差分だけ」「3ステップで」
- 「まずは テスト追加だけ」
- 「例外処理やログは触らないで」
17-6. コピペ用:SoCチェックリスト✅🧱✨
- UIイベント内に SQL/HTTP/ファイル が出てきてない?🗄️🌐
- UIイベント内に 業務ルール(割引/状態遷移/制約) が直書きされてない?🧠
- UseCaseが UIの型(TextBox等) を触ってない?🖥️
- Domainが DB/ORM/JSON/HTTP を参照してない?🚫
- テストしたいロジックが I/O無しで呼べる形 になってる?🧪