project-structure について
project-structure は、.NET のソリューションとプロジェクトの構成規約をまとめたスキルです。共有ビルド設定、NuGet バージョンの一元管理、ソースとテストの分離、命名規則を扱います。
主な機能
- 01NuGet パッケージバージョンの一元管理
- 02共有 MSBuild プロパティ
- 03.slnx ソリューション形式の指針
- 04src/ と tests/ ディレクトリの分離
- 05プロジェクトと名前空間の命名規則
- 06global.json による SDK バージョン固定
活用シーン
- 01新しい .NET ソリューションの構成
- 02パッケージバージョンの一元管理
- 03複数プロジェクトのビルド設定の統一
- 04ソースプロジェクトとテストプロジェクトの分離
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ codewithmukesh/ dotnet-claude-kit --skill project-structureインストール後、Claude Code で/project-structureを入力して読み込まれたか確認します。
詳細
プロジェクト構成
基本原則
- パッケージ管理の一元化 —
Directory.Packages.propsを使用して、NuGet パッケージのバージョンを一か所で管理します。個々の.csprojファイルにはバージョン番号を記載しません。 - ビルドプロパティの共有 —
Directory.Build.propsを使用して、共通設定(ターゲットフレームワーク、nullable、暗黙的な using)を管理します。各プロジェクトで繰り返し記述しないでください。 - ソリューションには .slnx を使用 — 新しい XML ベースのソリューション形式は、従来の
.sln形式より簡潔で、マージしやすい形式です。 - src/tests の分離 — ソースプロジェクトは
src/、テストプロジェクトはtests/に配置します。明確に分離します。
パターン
ソリューションの構成
MyApp/
├── MyApp.slnx # Solution file
├── Directory.Build.props # Shared MSBuild properties
├── Directory.Packages.props # Central package management
├── .editorconfig # Code style rules
├── .gitignore
├── global.json # SDK version pinning
├── src/
│ ├── MyApp.Api/ # Web API (entry point)
│ │ ├── MyApp.Api.csproj
│ │ ├── Program.cs
│ │ └── Features/
│ ├── MyApp.Domain/ # Domain entities, value objects (optional)
│ │ └── MyApp.Domain.csproj
│ └── MyApp.Infrastructure/ # EF Core, external services (optional)
│ └── MyApp.Infrastructure.csproj
└── tests/
└── MyApp.Api.Tests/
└── MyApp.Api.Tests.csproj
Directory.Build.props
<Project>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>14</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
</Project>
Directory.Packages.props(パッケージ管理の一元化)
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Mediator.Abstractions" Version="3.0.0" />
<PackageVersion Include="Mediator.SourceGenerator" Version="3.0.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.10" />
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
<PackageVersion Include="xunit.v3" Version="3.2.2" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.10" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.13.0" />
</ItemGroup>
</Project>
パッケージ管理を一元化したプロジェクトファイル(.csproj)
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Mediator.Abstractions" />
<PackageReference Include="Mediator.SourceGenerator" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" />
<PackageReference Include="Microsoft.EntityFrameworkCore" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<PackageReference Include="Serilog.AspNetCore" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyApp.Domain\MyApp.Domain.csproj" />
<ProjectReference Include="..\MyApp.Infrastructure\MyApp.Infrastructure.csproj" />
</ItemGroup>
</Project>
global.json(SDK の固定)
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
.slnx ソリューション形式
<Solution>
<Folder Name="/src/">
<Project Path="src/MyApp.Api/MyApp.Api.csproj" />
<Project Path="src/MyApp.Domain/MyApp.Domain.csproj" />
<Project Path="src/MyApp.Infrastructure/MyApp.Infrastructure.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/MyApp.Api.Tests/MyApp.Api.Tests.csproj" />
</Folder>
</Solution>
命名規則
| 要素 | 規則 | 例 |
|---|---|---|
| ソリューション | CompanyName.AppName または AppName | MyApp.slnx |
| プロジェクト | AppName.Layer | MyApp.Api、MyApp.Domain |
| 名前空間 | フォルダーのパスに合わせる | MyApp.Api.Features.Orders |
| 機能フォルダー | PascalCase、複数形 | Features/Orders/ |
| テストプロジェクト | ProjectName.Tests | MyApp.Api.Tests |
アンチパターン
パッケージのバージョンを分散させない
<PackageReference Include="Mediator.Abstractions" Version="2.0.0" />
<PackageReference Include="Mediator.Abstractions" Version="3.0.0" />
ビルドプロパティを繰り返し記述しない
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
ソースプロジェクトとテストプロジェクトを混在させない
# BAD — tests mixed with source
src/
MyApp.Api/
MyApp.Api.Tests/ # test project in src/
# GOOD — clear separation
src/
MyApp.Api/
tests/
MyApp.Api.Tests/
選択ガイド
| シナリオ | 推奨事項 |
|---|---|
| 新しいソリューション | .slnx 形式 |
| パッケージのバージョン管理 | Directory.Packages.props(一元管理) |
| 共通のビルド設定 | Directory.Build.props |
| SDK バージョンの固定 | global.json |
| 共通の using ディレクティブ | Directory.Build.props のグローバル using |
| 小規模 API(開発者 1~2 名) | 単一プロジェクト(MyApp.Api) |
| 中規模 API(開発者 3~5 名) | 2~3 個のプロジェクト(Api、Domain、Infrastructure) |
| 大規模/モジュール型アプリ | モジュールごとのプロジェクトと、共有の Contracts |
コメント
Markdown 対応