mcpField
D
dotnet-project-structure

dotnet-project-structure

github.com/aaronontheweb開発1.2k670 回インストール今日更新
リポジトリ

dotnet-project-structure について

.NET ソリューションを構築する開発者向けに、ソリューション構成、ビルド設定の集約、バージョン管理を解説するスキルです。.slnx、NuGet パッケージバージョンの一元管理、SDK の固定、リリースノートを使ったバージョン更新を扱います。

主な機能

  1. 01.slnx ソリューションの作成と移行
  2. 02ビルドプロパティの集約
  3. 03NuGet パッケージバージョンの一元管理
  4. 04global.json による SDK の固定
  5. 05リリースノートに基づくバージョン更新

活用シーン

  1. 01新しい .NET ソリューションのファイル構成を計画
  2. 02複数プロジェクトのビルド設定とパッケージバージョンを統一
  3. 03環境間で指定 SDK バージョンを使用
  4. 04リリースノートをバージョン更新とビルドに連携

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/aaronontheweb/dotnet-skills --skill dotnet-project-structure

インストール後、Claude Code で/dotnet-project-structureを入力して読み込まれたか確認します。

詳細

.NET プロジェクト構成とビルド構成

このスキルを使用するタイミング

次の場合にこのスキルを使用します:

  • 最新のベストプラクティスに沿って新しい .NET ソリューションをセットアップするとき
  • 複数のプロジェクトに適用するビルドプロパティを一元管理するとき
  • パッケージバージョンの一元管理を実装するとき
  • デバッグと NuGet パッケージのために SourceLink をセットアップするとき
  • リリースノートを使ったバージョン管理を自動化するとき
  • 一貫したビルドのために SDK バージョンを固定するとき

関連スキル

  • dotnet-local-tools - dotnet-tools.json を使用したローカル .NET ツールの管理
  • microsoft-extensions-configuration - 構成の検証パターン

ソリューションファイル形式(.slnx)

.slnx 形式は、.NET 9 で導入された XML ベースの最新のソリューションファイル形式です。従来の .sln 形式に代わるものです。

従来の .sln と比較した利点
項目.sln(従来).slnx(最新)
形式独自のテキスト形式標準的な XML
読みやすさGUID と難解な構文明瞭で人が読みやすい
バージョン管理差分やマージが困難差分やマージが容易
編集IDE が必要任意のテキストエディター
バージョン要件
ツール最小バージョン
.NET SDK9.0.200
Visual Studio17.13
MSBuildVisual Studio Build Tools 17.13

注: .NET 10 以降では、dotnet new sln はデフォルトで .slnx ファイルを作成します。.NET 9 では、明示的に移行するか、形式を指定する必要があります。

.slnx ファイルの例
<Solution>
  <Folder Name="/build/">
    <File Path="Directory.Build.props" />
    <File Path="Directory.Packages.props" />
    <File Path="global.json" />
    <File Path="NuGet.Config" />
    <File Path="README.md" />
  </Folder>
  <Folder Name="/src/">
    <Project Path="src/MyApp/MyApp.csproj" />
    <Project Path="src/MyApp.Core/MyApp.Core.csproj" />
  </Folder>
  <Folder Name="/tests/">
    <Project Path="tests/MyApp.Tests/MyApp.Tests.csproj" />
  </Folder>
</Solution>
.sln から .slnx への移行

dotnet sln migrate コマンドを使用して、既存のソリューションを変換します:

# Migrate a specific solution file
dotnet sln MySolution.sln migrate

# Or if only one .sln exists in the directory, just run:
dotnet sln migrate

重要: 同じリポジトリに .sln ファイルと .slnx ファイルの両方を置かないでください。ソリューションの自動検出で問題が発生し、同期に支障をきたすことがあります。移行後は、古い .sln ファイルを削除してください。

Visual Studio で移行することもできます:

  1. ソリューションを開きます
  2. ソリューション エクスプローラーでソリューションを選択します
  3. File > Save Solution As... に移動します
  4. 「Save as type」を Xml Solution File (*.slnx) に変更します
新しい .slnx ソリューションの作成
# .NET 10+: Creates .slnx by default
dotnet new sln --name MySolution

# .NET 9: Specify the format explicitly
dotnet new sln --name MySolution --format slnx

# Add projects (works the same for both formats)
dotnet sln add src/MyApp/MyApp.csproj
推奨事項

.NET 9.0.200 以降を使用している場合は、ソリューションを .slnx に移行してください。 多くの利点があります:

  • マージの競合が大幅に減少します(ランダムな GUID が変わらないため)
  • 人が読みやすく、任意のテキストエディターで編集できます
  • 最新の .csproj 形式と一貫性があります
  • プルリクエストでの差分確認やレビューがしやすくなります

Directory.Build.props

Directory.Build.props は、ディレクトリツリー内のすべてのプロジェクトに適用されるビルド構成を一元管理します。ソリューションのルートに配置します。

完全な例
<Project>
  
  <PropertyGroup>
    <Authors>Your Team</Authors>
    <Company>Your Company</Company>
    
    <Copyright>Copyright © 2020-$([System.DateTime]::Now.Year) Your Company</Copyright>
    <Product>Your Product</Product>
    <PackageProjectUrl>https://github.com/yourorg/yourrepo</PackageProjectUrl>
    <RepositoryUrl>https://github.com/yourorg/yourrepo</RepositoryUrl>
    <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
    <PackageTags>your;tags;here</PackageTags>
  </PropertyGroup>

  
  <PropertyGroup>
    <LangVersion>latest</LangVersion>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <NoWarn>$(NoWarn);CS1591</NoWarn> 
  </PropertyGroup>

  
  <PropertyGroup>
    <VersionPrefix>1.0.0</VersionPrefix>
    <PackageReleaseNotes>See RELEASE_NOTES.md</PackageReleaseNotes>
  </PropertyGroup>

  
  <PropertyGroup>
    <NetStandardLibVersion>netstandard2.0</NetStandardLibVersion>
    <NetLibVersion>net8.0</NetLibVersion>
    <NetTestVersion>net9.0</NetTestVersion>
  </PropertyGroup>

  
  <PropertyGroup>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    <EmbedUntrackedSources>true</EmbedUntrackedSources>
    <IncludeSymbols>true</IncludeSymbols>
    <SymbolPackageFormat>snupkg</SymbolPackageFormat>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
  </ItemGroup>

  
  <ItemGroup>
    <None Include="$(MSBuildThisFileDirectory)logo.png" Pack="true" PackagePath="\" />
    <None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" />
  </ItemGroup>

  <PropertyGroup>
    <PackageIcon>logo.png</PackageIcon>
    <PackageReadmeFile>README.md</PackageReadmeFile>
  </PropertyGroup>

  
  <ItemGroup>
    <Using Include="System.Collections.Immutable" />
  </ItemGroup>
</Project>
主なパターン
動的な著作権年
<Copyright>Copyright © 2020-$([System.DateTime]::Now.Year) Your Company</Copyright>

MSBuild のプロパティ関数を使用して、ビルド時に現在の年を挿入します。手動で更新する必要はありません。

再利用可能なターゲット フレームワークのプロパティ

ターゲット フレームワークを一度定義し、各所で参照します:


<PropertyGroup>
  <NetLibVersion>net8.0</NetLibVersion>
  <NetTestVersion>net9.0</NetTestVersion>
</PropertyGroup>


<PropertyGroup>
  <TargetFramework>$(NetLibVersion)</TargetFramework>
</PropertyGroup>


<PropertyGroup>
  <TargetFramework>$(NetTestVersion)</TargetFramework>
</PropertyGroup>
NuGet パッケージの SourceLink

SourceLink を使用すると、NuGet パッケージのステップ実行デバッグが可能になります:

<PropertyGroup>
  <PublishRepositoryUrl>true</PublishRepositoryUrl>
  <EmbedUntrackedSources>true</EmbedUntrackedSources>
  <IncludeSymbols>true</IncludeSymbols>
  <SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

<ItemGroup>
  
  <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
  
  
  
</ItemGroup>

Directory.Packages.props - パッケージの一元管理

パッケージの一元管理(CPM)により、すべての NuGet パッケージバージョンの信頼できる唯一の情報源を用意できます。

セットアップ
<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>

  
  <PropertyGroup>
    <AkkaVersion>1.5.35</AkkaVersion>
    <AspireVersion>9.1.0</AspireVersion>
  </PropertyGroup>

  
  <ItemGroup Label="App Dependencies">
    <PackageVersion Include="Akka" Version="$(AkkaVersion)" />
    <PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />
    <PackageVersion Include="Akka.Persistence" Version="$(AkkaVersion)" />
    <PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
  </ItemGroup>

  
  <ItemGroup Label="Build Dependencies">
    <PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
  </ItemGroup>

  
  <ItemGroup Label="Test Dependencies">
    <PackageVersion Include="xunit" Version="2.9.3" />
    <PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
    <PackageVersion Include="FluentAssertions" Version="7.0.0" />
    <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
    <PackageVersion Include="coverlet.collector" Version="6.0.3" />
  </ItemGroup>
</Project>
パッケージの使用(バージョン指定不要)

<ItemGroup>
  <PackageReference Include="Akka" />
  <PackageReference Include="Akka.Cluster" />
  <PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>


<ItemGroup>
  <PackageReference Include="xunit" />
  <PackageReference Include="FluentAssertions" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" />
</ItemGroup>
利点
  1. 信頼できる唯一の情報源 - すべてのバージョンを1つのファイルで管理します
  2. バージョンの不整合を防止 - すべてのプロジェクトで同じバージョンを使用します
  3. 簡単な更新 - 一度変更するだけで、すべてに適用されます
  4. パッケージのグループ化 - 関連するパッケージ(例:すべての Akka パッケージ)にバージョン変数を使用します

global.json - SDK バージョンの固定

すべての環境で一貫したビルドを行うために、.NET SDK のバージョンを固定します。

{
  "sdk": {
    "version": "9.0.200",
    "rollForward": "latestFeature"
  }
}
ロールフォワードポリシー
ポリシー動作
disable正確なバージョンが必要です
patch同じ major.minor の最新 patch
feature同じ major の最新 minor.patch
latestFeature同じ major の最新 feature バンド
minor同じ major の最新 minor
latestMinor同じ major の最新 minor
major最新の SDK(推奨されません)

推奨: latestFeature - 同じ feature バンド内での patch 更新を許可します。


RELEASE_NOTES.md によるバージョン管理

リリースノートの形式
#### 1.2.0 January 15th 2025 ####

- Added new feature X
- Fixed bug in Y
- Improved performance of Z

#### 1.1.0 December 10th 2024 ####

- Initial release with features A, B, C
解析スクリプト(getReleaseNotes.ps1)
function Get-ReleaseNotes {
    param (
        [Parameter(Mandatory=$true)]
        [string]$MarkdownFile
    )

    $content = Get-Content -Path $MarkdownFile -Raw
    $sections = $content -split "####"

    $result = [PSCustomObject]@{
        Version      = $null
        Date         = $null
        ReleaseNotes = $null
    }

    if ($sections.Count -ge 3) {
        $header = $sections[1].Trim()
        $releaseNotes = $sections[2].Trim()

        $headerParts = $header -split " ", 2
        if ($headerParts.Count -eq 2) {
            $result.Version = $headerParts[0]
            $result.Date = $headerParts[1]
        }

        $result.ReleaseNotes = $releaseNotes
    }

    return $result
}
バージョン更新スクリプト(bumpVersion.ps1)
function UpdateVersionAndReleaseNotes {
    param (
        [Parameter(Mandatory=$true)]
        [PSCustomObject]$ReleaseNotesResult,
        [Parameter(Mandatory=$true)]
        [string]$XmlFilePath
    )

    $xmlContent = New-Object XML
    $xmlContent.Load($XmlFilePath)

    # Update VersionPrefix
    $versionElement = $xmlContent.SelectSingleNode("//VersionPrefix")
    $versionElement.InnerText = $ReleaseNotesResult.Version

    # Update PackageReleaseNotes
    $notesElement = $xmlContent.SelectSingleNode("//PackageReleaseNotes")
    $notesElement.InnerText = $ReleaseNotesResult.ReleaseNotes

    $xmlContent.Save($XmlFilePath)
}
ビルドスクリプト(build.ps1)
# Load helper scripts
. "$PSScriptRoot\scripts\getReleaseNotes.ps1"
. "$PSScriptRoot\scripts\bumpVersion.ps1"

# Parse release notes and update Directory.Build.props
$releaseNotes = Get-ReleaseNotes -MarkdownFile (Join-Path -Path $PSScriptRoot -ChildPath "RELEASE_NOTES.md")
UpdateVersionAndReleaseNotes -ReleaseNotesResult $releaseNotes -XmlFilePath (Join-Path -Path $PSScriptRoot -ChildPath "Directory.Build.props")

Write-Output "Updated to version $($releaseNotes.Version)"
CI/CD の統合
# GitHub Actions example
- name: Update version from release notes
  shell: pwsh
  run: ./build.ps1

- name: Build
  run: dotnet build -c Release

- name: Pack with tag version
  run: dotnet pack -c Release /p:PackageVersion=${{ github.ref_name }}

- name: Push to NuGet
  run: dotnet nuget push **/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json

NuGet.Config

NuGet のソースと動作を設定します:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <solution>
    <add key="disableSourceControlIntegration" value="true" />
  </solution>

  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    
    
  </packageSources>
</configuration>

主な設定:

  • <clear /> - 再現可能なビルドのため、継承されたソースおよび既定のソースを削除します
  • disableSourceControlIntegration - TFS/Git の統合に関する問題を防ぎます

プロジェクト構造の全体像

MySolution/
├── .config/
│   └── dotnet-tools.json           # Local .NET tools
├── .github/
│   └── workflows/
│       ├── pr-validation.yml       # PR checks
│       └── release.yml             # NuGet publishing
├── scripts/
│   ├── getReleaseNotes.ps1         # Parse RELEASE_NOTES.md
│   └── bumpVersion.ps1             # Update Directory.Build.props
├── src/
│   ├── MyApp/
│   │   └── MyApp.csproj
│   └── MyApp.Core/
│       └── MyApp.Core.csproj
├── tests/
│   └── MyApp.Tests/
│       └── MyApp.Tests.csproj
├── Directory.Build.props           # Centralized build config
├── Directory.Packages.props        # Central package versions
├── MySolution.slnx                 # Modern solution file
├── global.json                     # SDK version pinning
├── NuGet.Config                    # Package source config
├── build.ps1                       # Build orchestration
├── RELEASE_NOTES.md                # Version history
├── README.md                       # Project documentation
└── logo.png                        # Package icon

クイックリファレンス

ファイル用途
MySolution.slnx最新の XML ソリューションファイル
Directory.Build.propsビルドプロパティの一元管理
Directory.Packages.propsパッケージバージョンの一元管理
global.jsonSDK バージョンの固定
NuGet.Configパッケージソースの設定
RELEASE_NOTES.mdバージョン履歴(ビルド時に解析)
build.ps1ビルドオーケストレーションスクリプト
.config/dotnet-tools.jsonローカル .NET ツール

コメント