Skip to main content

wpf-clean-architecture-mvvm

Design guidelines for WPF applications using .NET 10 C#, MVVM Toolkit, Clean Architecture, Modular Monolith, and .NET Aspire. Use this skill when creating, modifying, or reviewing any part of this application's architecture, project structure, or code organization.

来源信息

仓库
runceel/wpf-github-copilot
最近来源活动
2026年4月18日 04:58
检测到的 SKILL.md 语言
日语
星标
0
分支
0

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
4 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
wpf-clean-architecture-mvvm
description
Design guidelines for WPF applications using .NET 10 C#, MVVM Toolkit, Clean Architecture, Modular Monolith, and .NET Aspire. Use this skill when creating, modifying, or reviewing any part of this application's architecture, project structure, or code organization.
# WPF Clean Architecture + Modular Monolith + Aspire Design Guidelines **.NET 10 C# + WPF** で **MVVM Toolkit**・**クリーンアーキテクチャ**・**モジュラーモノリス**・**.NET Aspire** を組み合わせて構築します。 ## 参照ドキュメント | ドキュメント | 内容 | |---|---| | [shell-pattern.md](references/shell-pattern.md) | IModule・IShellService のインターフェース定義と全実装例 | | [aspire-integration.md](references/aspire-integration.md) | Aspire 統合の詳細設定・コード例 | | [project-settings.md](references/project-settings.md) | 各プロジェクトの `.csproj` 設定とプロジェクト参照の例 | --- ## ソリューション構成 ``` src/ AspireAppHost/ # Aspire オーケストレーター(バックエンドインフラ管理) ServiceDefaults/ # OpenTelemetry・サービスディスカバリの共通設定 WpfApp/ # WPF シェル(最小限のグルーコードのみ) Shared/ Shared.Kernel/ # ドメインプリミティブ(WPF 非依存) Shared.UI/ # UI プリミティブ(IModule・IShellService・共通スタイル) Modules/ {ModuleName}/ {ModuleName}.Domain/ {ModuleName}.Application/ {ModuleName}.Infrastructure/ {ModuleName}.Presentation/ # Views・ViewModels・IModule 実装 tests/ {ModuleName}.{Layer}.Tests/ ``` --- ## モジュラーモノリスのルール - **モジュール間の直接参照は禁止**。モジュール間通信は `Shared.Kernel` 経由(イベント・インターフェース・共通 DTO)のみ。 - **UI もモジュールが所有する**。Views・ViewModels・ナビゲーション登録はすべて `Presentation` 層が管理する。 - **`WpfApp` は薄いシェルのみ**。`IModule` の列挙・初期化とシェル UI(ウィンドウ枠)だけを持ち、ビジネス知識を持たない。 - 各モジュールは DI 登録拡張メソッドを `Infrastructure` 層(`AddXxxModule`)と `Presentation` 層(`AddXxxPresentation`)にそれぞれ実装する。 --- ## クリーンアーキテクチャ 各層の責務 | 層 | 依存先 | 主な内容 | |---|---|---| | **Domain** | `Shared.Kernel` のみ | エンティティ・値オブジェクト・集約ルート・リポジトリ IF・ドメイン例外 | | **Application** | Domain・Shared.Kernel | コマンド/クエリ・ハンドラー・DTO・バリデーション・ドメインイベントハンドラー | | **Infrastructure** | Application・Domain・Shared.Kernel | リポジトリ実装・EF Core・外部クライアント・DI 登録 | | **Presentation** | Application・Shared.Kernel・Shared.UI | Views (XAML)・ViewModels (MVVM Toolkit)・`IModule` 実装・DI 登録 | --- ## MVVM Toolkit 使用規則 - ViewModel は `ObservableObject` を継承した `partial class` で定義する。 - プロパティは `[ObservableProperty]`(フィールド名 `_camelCase`)、コマンドは `[RelayCommand]` で生成する。 - プロパティ変更時の副作用は `partial void OnXxxChanged(T value)` で対応する。 - `CanExecute` は `[RelayCommand(CanExecute = nameof(CanXxx))]` で指定する。 - ViewModel と View は Presentation 層の `AddXxxPresentation()` で DI 登録する。 ```csharp public partial class OrderListViewModel(IOrderQueryService queryService) : ObservableObject { [ObservableProperty] private ObservableCollection<OrderDto> _orders = []; [ObservableProperty] private bool _isLoading; [RelayCommand] private async Task LoadOrdersAsync(CancellationToken ct) { IsLoading = true; try { Orders = new(await queryService.GetAllAsync(ct)); } finally { IsLoading = false; } } } ``` --- ## Shared.Kernel の内容(WPF 非依存) `Entity<TId>`・`ValueObject`・`AggregateRoot<TId>`・`IDomainEvent`・`Result<T>`・共通例外基底・`IEventBus` ## Shared.UI の内容(WPF 依存) `IModule`・`IShellService`・`NavigationItem`・共通 `ResourceDictionary`(テーマ・スタイル)・共通コンバーター基底 インターフェース定義と実装例 → [shell-pattern.md](references/shell-pattern.md) --- ## WpfApp(シェル)の責務 Generic Host (`Host.CreateApplicationBuilder()`) で起動し、`AddServiceDefaults()` を組み込む。 1. `ShellService` / `MainWindowViewModel` / `MainWindow` を DI 登録 2. 各モジュールの `AddXxxModule()` + `AddXxxPresentation()` を呼び出す 3. ビルド後、全 `IModule` を取得して `module.Initialize(shell)` を実行 4. `MainWindow` を表示する 完全なコード → [shell-pattern.md](references/shell-pattern.md) --- ## .NET Aspire 統合 - `AspireAppHost` はバックエンドインフラ(DB・API・キュー等)をオーケストレートする。WPF アプリは登録しない(手動起動)。 - `ServiceDefaults` を `WpfApp` から参照し、`AddServiceDefaults()` でテレメトリ・サービスディスカバリを有効化する。 - バックエンド API への接続は `https+http://{サービス名}` で行う(Aspire のサービスディスカバリ)。 詳細・コード例 → [aspire-integration.md](references/aspire-integration.md) --- ## 依存方向のルール(厳守) ``` Presentation → Application → Domain Presentation → Shared.UI Infrastructure → Application → Domain WpfApp → {ModuleName}.Presentation(IModule 列挙のため) WpfApp → Shared.UI Shared.Kernel ← すべての層から参照可(UI 依存なし) Shared.UI ← Presentation・WpfApp のみ参照可 AspireAppHost → バックエンドサービスプロジェクトのみ モジュール間の直接参照 → 禁止 ``` プロジェクトファイルと参照の設定例 → [project-settings.md](references/project-settings.md) --- ## コード生成時のチェックリスト 1. **新しいモジュール**: Domain → Application → Infrastructure → Presentation の順に4プロジェクトを作成し、Presentation から `Shared.UI` を参照する。 2. **ViewModel**: `ObservableObject` + `partial class` + `[ObservableProperty]`/`[RelayCommand]`。 3. **ナビゲーション画面の追加**: `IModule.Initialize()` に `NavigationItem` を登録し、View と ViewModel を DI 登録する。 4. **モジュール間通信**: `Shared.Kernel` の `IEventBus` や共通 DTO を経由する。モジュール直接参照は禁止。 5. **新しいユースケース**: Application 層にコマンド/クエリ+ハンドラーを追加し、ドメインロジックは Domain 層に保持する。 6. **バックエンドサービス追加**: `AspireAppHost` に登録し、Infrastructure 層で `https+http://{サービス名}` でアクセスする。 7. **新規プロジェクト作成**: `ServiceDefaults` を参照し、ホストビルダーで `AddServiceDefaults()` を呼び出す。
在 GitHub 查看