package-management について
dotnet CLI で .NET プロジェクトの NuGet パッケージを管理するスキルです。パッケージ操作、Central Package Management、復元時の問題、プロジェクト間のバージョン管理を扱います。
主な機能
- 01dotnet コマンドでのパッケージ管理
- 02Central Package Management の設定
- 03古いパッケージと推移的依存関係の一覧
- 04パッケージの復元とキャッシュ消去
- 05バージョン競合の調査
- 06再現可能なビルドのためのロックファイル
活用シーン
- 01NuGet 依存関係の追加や削除
- 02ソリューション内プロジェクトのバージョン管理
- 03パッケージ復元エラーの診断
- 04依存関係の競合調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ aaronontheweb/ dotnet-skills --skill package-managementインストール後、Claude Code で/package-managementを入力して読み込まれたか確認します。
詳細
NuGet パッケージ管理
このスキルを使用する場面
次の場合にこのスキルを使用します:
- NuGet パッケージを追加、削除、または更新するとき
- ソリューションで Central Package Management(CPM)を設定するとき
- 複数のプロジェクト間でパッケージのバージョンを管理するとき
- パッケージの競合や復元の問題をトラブルシューティングするとき
黄金律:XMLを直接編集しない
パッケージの管理には、必ず dotnet CLI コマンドを使用してください。 .csproj ファイルや Directory.Packages.props ファイルを手動で編集しないでください。
# DO: Use CLI commands
dotnet add package Newtonsoft.Json
dotnet remove package Newtonsoft.Json
dotnet list package --outdated
# DON'T: Edit XML directly
# <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
理由:
- CLI がパッケージの存在を検証し、適切なバージョンを解決します
- 推移的な依存関係を正しく処理します
- ロックファイルが存在する場合は更新します
- タイプミスや不正な XML を防ぎます
- CPM で正しく動作します
Central Package Management(CPM)
CPM はすべてのパッケージバージョンを1つのファイルに集約し、プロジェクト間のバージョン競合を解消します。
CPM を有効にする
ソリューションのルートに Directory.Packages.props を作成します:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Serilog" Version="4.0.0" />
<PackageVersion Include="xunit" Version="2.9.2" />
</ItemGroup>
</Project>
CPM を使用するプロジェクトファイル
プロジェクトでは、パッケージをバージョンを指定せずに参照します:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Serilog" />
</ItemGroup>
</Project>
CPM でパッケージを追加する
# Adds to Directory.Packages.props AND project file
dotnet add package Serilog.Sinks.Console
# Result in Directory.Packages.props:
# <PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
# Result in project file:
# <PackageReference Include="Serilog.Sinks.Console" />
共有バージョン変数
関連するパッケージを共有バージョン変数でグループ化します:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<PropertyGroup Label="SharedVersions">
<AkkaVersion>1.5.59</AkkaVersion>
<AkkaHostingVersion>1.5.59</AkkaHostingVersion>
<AspireVersion>9.0.0</AspireVersion>
<OpenTelemetryVersion>1.11.0</OpenTelemetryVersion>
<XunitVersion>2.9.2</XunitVersion>
</PropertyGroup>
<ItemGroup Label="Akka.NET">
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster.Sharding" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster.Tools" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Persistence" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Streams" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Hosting" Version="$(AkkaHostingVersion)" />
<PackageVersion Include="Akka.Cluster.Hosting" Version="$(AkkaHostingVersion)" />
</ItemGroup>
<ItemGroup Label="Aspire">
<PackageVersion Include="Aspire.Hosting" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="$(AspireVersion)" />
</ItemGroup>
<ItemGroup Label="OpenTelemetry">
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="$(OpenTelemetryVersion)" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="$(OpenTelemetryVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="$(OpenTelemetryVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="$(OpenTelemetryVersion)" />
</ItemGroup>
<ItemGroup Label="Testing">
<PackageVersion Include="xunit" Version="$(XunitVersion)" />
<PackageVersion Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="Verify.Xunit" Version="26.0.0" />
</ItemGroup>
</Project>
メリット:
- 1つの変数を変更するだけで、すべての Akka パッケージを更新できます
- ラベル付きの ItemGroup により、明確に整理できます
- 関連パッケージ間でのバージョン不一致を防ぎます
CPM を使用しないほうがよい場合
Central Package Management が常に適切な選択とは限りません:
レガシープロジェクト
既存の大規模なソリューションを CPM に移行すると、問題が発生することがあります:
- 既存のバージョン競合が一度に明らかになります
- 一部のパッケージでは、意図的にバージョンを変えている場合があります
- 移行には、多数のファイルを同時に変更する必要があります
推奨:レガシープロジェクトでは、段階的に移行するか、現在問題なく機能している場合はプロジェクトごとのバージョン管理を継続してください。
バージョン範囲
CPM では厳密なバージョンが必要であり、バージョン範囲はサポートされません:
<PackageVersion Include="Newtonsoft.Json" Version="[13.0,14.0)" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
バージョン範囲が必要な場合(まれですが、一部のライブラリの用途で必要になります)、CPM は使用できません。
古い .NET バージョン
CPM には次の要件があります:
- .NET SDK 6.0.300+ またはそれ以降
- NuGet 6.2+ またはそれ以降
- Visual Studio 2022 17.2+ またはそれ以降
古い SDK バージョンを対象にしている場合や、チームメンバーが古いツールを使用している場合、CPM によってビルドに失敗することがあります。
複数リポジトリにまたがるソリューション
ソリューションが、個別にビルドされる複数のリポジトリにまたがる場合、CPM の単一の Directory.Packages.props は役に立ちません。各リポジトリでそれぞれ必要になります。
CLI コマンドリファレンス
パッケージの追加
# Add latest stable version
dotnet add package Serilog
# Add specific version
dotnet add package Serilog --version 4.0.0
# Add prerelease
dotnet add package Serilog --prerelease
# Add to specific project
dotnet add src/MyApp/MyApp.csproj package Serilog
パッケージの削除
# Remove from current project
dotnet remove package Serilog
# Remove from specific project
dotnet remove src/MyApp/MyApp.csproj package Serilog
パッケージの一覧表示
# List all packages in solution
dotnet list package
# Show outdated packages
dotnet list package --outdated
# Include transitive dependencies
dotnet list package --include-transitive
# Show vulnerable packages
dotnet list package --vulnerable
# Show deprecated packages
dotnet list package --deprecated
パッケージの更新
# With CPM: Edit the version in Directory.Packages.props
# Then restore to apply
dotnet restore
# Without CPM: Remove and add with new version
dotnet remove package Serilog
dotnet add package Serilog --version 4.1.0
# Or use dotnet-outdated tool (recommended)
dotnet tool install --global dotnet-outdated-tool
dotnet outdated --upgrade
復元とクリーンアップ
# Restore packages
dotnet restore
# Clear local cache (troubleshooting)
dotnet nuget locals all --clear
# Force restore (ignore cache)
dotnet restore --force
パッケージソース
ソースの一覧表示
dotnet nuget list source
プライベートフィードの追加
# Add authenticated feed
dotnet nuget add source https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json \
--name MyFeed \
--username az \
--password $PAT \
--store-password-in-clear-text
NuGet.config
ソリューション固有のソースを設定するには、NuGet.config を作成します:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="MyPrivateFeed" value="https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<MyPrivateFeed>
<add key="Username" value="az" />
<add key="ClearTextPassword" value="%NUGET_PAT%" />
</MyPrivateFeed>
</packageSourceCredentials>
</configuration>
よくあるパターン
開発時のみ使用するパッケージ
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
条件付きパッケージ
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<PackageReference Include="JetBrains.Annotations" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.Text.Json" />
</ItemGroup>
バージョンの上書き(最終手段)
1つのプロジェクトで CPM を上書きする必要がある場合(まれです):
<PackageReference Include="Newtonsoft.Json" VersionOverride="12.0.3" />
警告:これは Slopwatch により、潜在的なスロップとして検出されます(dotnet/slopwatch スキルを参照)。
トラブルシューティング
バージョン競合
# See full dependency tree
dotnet list package --include-transitive
# Find what's pulling in a specific package
dotnet list package --include-transitive | grep -i "PackageName"
復元の失敗
# Clear all caches
dotnet nuget locals all --clear
# Restore with detailed logging
dotnet restore --verbosity detailed
# Check for locked packages
cat packages.lock.json
ロックファイル
再現可能なビルドを行うには、パッケージロックファイルを使用します:
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
その後、packages.lock.json ファイルをコミットします。
アンチパターン
やってはいけないこと:XML を直接編集する
<PackageReference Include="Typo.Package" Version="1.0.0" />
やってはいけないこと:CPM でバージョンをインライン指定する
<PackageReference Include="Serilog" Version="4.0.0" />
<PackageReference Include="Serilog" />
やってはいけないこと:バージョン管理方法を混在させる
<PackageReference Include="Serilog" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
やってはいけないこと:共有変数を忘れる
<PackageVersion Include="Akka" Version="1.5.59" />
<PackageVersion Include="Akka.Cluster" Version="1.5.58" />
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />
クイックリファレンス
| タスク | コマンド |
|---|---|
| パッケージを追加 | dotnet add package <name> |
| 特定のバージョンを追加 | dotnet add package <name> --version <ver> |
| パッケージを削除 | dotnet remove package <name> |
| パッケージを一覧表示 | dotnet list package |
| 古いパッケージを表示 | dotnet list package --outdated |
| 脆弱性のあるパッケージを表示 | dotnet list package --vulnerable |
| 復元 | dotnet restore |
| キャッシュをクリア | dotnet nuget locals all --clear |
Resources
- Central Package Management: https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management
- dotnet CLI Reference: https://learn.microsoft.com/en-us/dotnet/core/tools/
- NuGet.config Reference: https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file