依存関係管理は、NuGet のコア機能です。 1 つのプロジェクトの依存関係の管理は簡単ですが、ソリューション内のプロジェクトの数が増えるにつれてますます複雑になります。
多くの異なるプロジェクトの共通依存関係を管理する場合は、NuGet の中央パッケージ管理 (CPM) 機能を利用して、このすべてを 1 つの中央の場所から実行できます。
中央パッケージ管理は、すべての <PackageReference>
ベースの MSBuild プロジェクト ( レガシ CSPROJ を含む) に適用されます。
中央パッケージ管理の有効化
中央パッケージ管理を開始するには、リポジトリのルートに Directory.Packages.props
ファイルを作成し、MSBuild プロパティの ManagePackageVersionsCentrally
を true
に設定します。
手動で作成することも、.NET CLI を使用することもできます。
dotnet new packagesprops
Directory.Packages.props
内で、<PackageVersion />
要素を定義して、プロジェクトで使用されるパッケージ ID とバージョンを指定します。
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
各プロジェクト ファイルで、Version
属性を持たない<PackageReference />
要素を定義します。
バージョンは、Directory.Packages.props
の対応する<PackageVersion />
エントリから解決されます。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
これで、中央パッケージ管理を使用し、中央の場所でバージョンを管理します。
中央パッケージ管理規則
Directory.Packages.props
ファイルには、リポジトリ内の場所とコンテキストに関する特定の規則があります。
既定では、特定のプロジェクトに対して評価される Directory.Packages.props
ファイルは 1 つだけです。
リポジトリに複数の Directory.Packages.props
ファイルがある場合は、特定のプロジェクトのディレクトリに最も近いファイルが評価されます。
これにより、リポジトリのさまざまなレベルで追加の制御が可能になります。
次のリポジトリ ディレクトリ構造を考えてみましょう。
📂 (root)
├─📄 Directory.Packages.props
|
├─📂Solution1
| ├─ 📄Directory.Packages.props
| |
| └─ 📂 Project1
| └─📄Project1.csproj
|
└─ 📂 Solution2
└─ 📂 Project2
└─ 📄 Project2.csproj
Project1.csproj
は、Repository\Solution1\
ディレクトリ内のDirectory.Packages.props
ファイルを使用します。
親 Directory.Packages.props
の設定を含める場合は、手動でインポートする必要があります。
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
<ItemGroup>
<PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
</ItemGroup>
</Project>
Project2.csproj
は、ルート ディレクトリ内の Directory.Packages.props
ファイルを評価します。
手記
MSBuild は、プロジェクト ディレクトリまたは親ディレクトリで検出された最初の Directory.Packages.props
ファイルのみを自動的にインポートします。
このようなファイルが複数ある場合は、必要に応じて親ファイルを手動でインポートする必要があります。
はじめに
リポジトリを完全にオンボードするには、次の手順に従います。
-
Directory.Packages.props
という名前のリポジトリのルートに新しいファイルを作成し、一元的に定義されたパッケージ バージョンを宣言し、MSBuild プロパティのManagePackageVersionsCentrally
をtrue
に設定します。 -
<PackageVersion />
でDirectory.Packages.props
項目を宣言します。 - プロジェクトファイルで、
<PackageReference />
属性なしでVersion
項目を宣言します。
中央パッケージ管理の外観の例については、 サンプル リポジトリを参照してください。
異なるターゲット フレームワークに異なるバージョンを使用する
NuGet パッケージが進化するにつれて、パッケージ所有者は古いターゲット フレームワークのサポートを削除する可能性があります。 これにより、古いフレームワークをまだ対象としているが、新しいターゲット フレームワーク用に新しいバージョンのパッケージを参照する必要があるライブラリの開発者に問題が発生する可能性があります。
たとえば、プロジェクトのターゲットが .NET Standard 2.0、.NET 8.0、.NET Framework 4.7.2 であっても、最新バージョンの .NET Standard 2.0 がサポートされなくなった PackageA
は、ターゲット フレームワークごとに異なるバージョンを指定できます。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net8.0;net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
この場合は、MSBuild 条件を使用して、Directory.Packages.props
内のターゲット フレームワークごとに異なるバージョンを定義します。
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<PackageVersion Include="PackageA" Version="2.0.0" Condition="'$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net472'" />
</ItemGroup>
</Project>
推移的なピン留め
推移的なピン留めと呼ばれる機能を選択することで、明示的な最上位 <PackageReference />
項目なしで推移的なパッケージ バージョンを自動的にオーバーライドできます。
これにより、必要に応じて、推移的な依存関係が、ユーザーの代わりに暗黙的に最上位の依存関係に昇格します。
パッケージを推移的にピン留めする場合、ダウングレードは許可されないことに注意してください。 依存関係によって要求されたバージョンよりも低いバージョンにパッケージをピン留めしようとすると、復元時に NU1109 エラーが発生します。
この機能を有効にするには、プロジェクトまたは CentralPackageTransitivePinningEnabled
、true
で、MSBuild プロパティ Directory.Packages.props
を Directory.Build.props
に設定します。
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
推移的なピン留めとパック
パッケージが推移的にピン留めされている場合、プロジェクトでは依存関係によって要求されたバージョンよりも高いバージョンが使用されます。 プロジェクトからパッケージを作成し、パッケージが確実に機能するようにすると、NuGet は推移的にピン留めされた依存関係を nuspec 内の明示的な依存関係に昇格させます。
次の例では、PackageA 1.0.0
は PackageB 1.0.0
に依存しています。
<Project>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
pack コマンドを使用してパッケージを作成すると、両方のパッケージが依存関係グループに表示されます。
<group targetFramework="net6.0">
<dependency id="PackageA" version="1.0.0" exclude="Build,Analyzers" />
<dependency id="PackageB" version="2.0.0" exclude="Build,Analyzers" />
</group>
このため、ライブラリを作成するときに推移的なピン留めの使用を慎重に評価する必要があります。これは、予期していなかった依存関係につながる可能性があるためです。
パッケージ バージョンのオーバーライド
VersionOverride
項目の <PackageReference />
プロパティを使用して、個々のパッケージ バージョンをオーバーライドできます。
これは、一元的に定義された <PackageVersion />
よりも優先されます。
<Project>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" VersionOverride="3.0.0" />
</ItemGroup>
</Project>
この機能を無効にするには、MSBuild プロパティ CentralPackageVersionOverrideEnabled
を false
に設定し、プロジェクトや Directory.Packages.props
、Directory.Build.props
インポート ファイルで指定してください。
<PropertyGroup>
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>
この機能を無効にすると、VersionOverride
項目に <PackageReference />
を指定すると、復元時に機能が無効であることを示すエラーが発生します。
中央パッケージ管理の無効化
特定のプロジェクトの中央パッケージ管理を無効にするには、MSBuild プロパティ ManagePackageVersionsCentrally
を false
に設定します。
<PropertyGroup>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
グローバル パッケージ参照
手記
この機能は、Visual Studio 2022 17.4 以降、.NET SDK 7.0.100.preview7 以降、および NuGet 6.4 以降でのみ使用できます。
グローバル パッケージ参照は、リポジトリ内のすべてのプロジェクトでパッケージを使用することを指定するために使用されます。 これには、バージョン管理を行うパッケージ、ビルドを拡張するパッケージ、またはすべてのプロジェクトで必要なその他のパッケージが含まれます。 グローバル パッケージ参照は、次のメタデータを使用して PackageReference 項目グループに追加されます。
IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"
これにより、パッケージが開発依存関係としてのみ使用され、コンパイル時のアセンブリ参照としてパッケージが含まれるのを防ぐことができます。PrivateAssets="All"
これにより、グローバル パッケージ参照がダウンストリームの依存関係によって取得されなくなります。
GlobalPackageReference
項目は、リポジトリ内のすべてのプロジェクトで使用される Directory.Packages.props
に配置する必要があります。
<Project>
<ItemGroup>
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.109" />
</ItemGroup>
</Project>
複数のパッケージ ソースを使用する場合の NU1507 警告
中央パッケージ管理を使用する場合、構成で複数のパッケージ ソースが定義されている場合、NuGet は NU1507
警告をログに記録します。
この警告を解決するには、パッケージ ソースを パッケージ ソース マッピング にマップするか、単一のパッケージ ソースを指定します。
There are 3 package sources defined in your configuration. When using Central Package Management, please map your package sources with package source mapping (https://aka.ms/nuget-package-source-mapping) or specify a single package source.