Central Package Management (CPM)

依存関係の管理は、NuGet のコア機能です。 1 つのプロジェクトの依存関係の管理は簡単です。 マルチプロジェクト ソリューションの依存関係の管理は、サイズと複雑さが増してくると困難になる可能性があります。 多くの異なるプロジェクトに共通の依存関係を管理する状況では、NuGet の Central Package Management (CPM) 機能を利用して、このすべてを 1 つの場所から簡単に行うことができます。

これまで、NuGet パッケージの依存関係は、次の 2 つの場所の 1 つで管理されています。

  • packages.config - プロジェクトで参照されるパッケージの一覧を管理するために古いプロジェクトの種類で使用される XML ファイル。
  • <PackageReference /> - MSBuild プロジェクトで使われる XML 要素は、NuGet パッケージの依存関係を定義します。

NuGet 6.2 以降では、Directory.Packages.props ファイルと MSBuild プロパティを追加することで、プロジェクト内の依存関係を一元的に管理できます。

この機能は、すべての NuGet 統合ツールで使用できます。それぞれ次のバージョン以降から対応しています。

古いツールでは、Central Package Management の構成と機能は無視されます。 この機能を最大限に使用するには、すべてのビルド環境で、互換性のあるツールの最新バージョンが使用されていることを確認してください。

互換性のあるツールが使用されている限り、Central Package Management は、すべての <PackageReference> ベースの MSBuild プロジェクト (レガシ CSPROJ を含む) に適用されます。

Central Package Management を有効にする

Central Package Management を使い始めるには、リポジトリのルートに Directory.Packages.props ファイルを作成し、MSBuild プロパティ ManagePackageVersionsCentrallytrue に設定する必要があります。

内部では、パッケージ ID とバージョンを定義する <PackageVersion /> 要素を使って、プロジェクトに必要な各パッケージのバージョンを定義します。

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
  </ItemGroup>
</Project>

各プロジェクトに対して、<PackageReference /> を定義しますが、バージョンは対応する <PackageVersion /> 項目から取得するため、Version 属性は省略します。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" />
  </ItemGroup>
</Project>

これで、Central Package Management を使用し、一元的な場所でバージョンを管理するようになります。

Central Package Management のルール

Directory.Packages.props ファイルには、リポジトリのディレクトリ内の場所とそのコンテキストに関して、いくつかのルールがあります。 簡素化するため、特定のプロジェクトについて評価される Directory.Packages.props ファイルは 1 つだけです。

つまり、リポジトリに複数の Directory.Packages.props ファイルがある場合は、プロジェクトのディレクトリに最も近いファイルが評価されます。 これにより、リポジトリのさまざまなレベルで追加の制御が可能になります。

ここの例では、次のようなリポジトリ構造を考えます。

Repository
 |-- Directory.Packages.props
 |-- Solution1
     |-- Directory.Packages.props
     |-- Project1
 |-- Solution2
     |-- Project2
  • Project1 では Repository\Solution1\ ディレクトリの Directory.Packages.props ファイルが評価されます。必要に応じて次のファイルを手動でインポートする必要があります。
    <Project>
      <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
      <ItemGroup>
        <PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
      </ItemGroup>
    </Project>
    
  • Project2 では、Repository\ ディレクトリの Directory.Packages.props ファイルが評価されます。

注: MSBuild では各 Directory.Packages.props を自動的にインポートするのではなく、プロジェクトに最も近い最初の 1 つだけをインポートします。 複数の Directory.Packages.props がある場合、親を手動でインポートする必要がありますが、ルート Directory.Packages.props はそうではありません。

作業の開始

リポジトリを完全にオンボードするには、次の手順のようにします。

  1. リポジトリのルートに Directory.Packages.props という名前の新しいファイルを作成し、一元的に定義されたパッケージのバージョンを宣言し、MSBuild プロパティ ManagePackageVersionsCentrallytrue に設定します。
  2. Directory.Packages.props<PackageVersion /> 項目を宣言します。
  3. プロジェクト ファイルで Version 属性を含まない <PackageReference /> 項目を宣言します。

Central Package Management がどのように記述されるかについては、サンプルのリポジトリを参照してください。

推移的なピン留め

推移的なピン留めと呼ばれる機能を使用することで、明示的な最上位レベルの <PackageReference /> がなくても、推移的なパッケージ バージョンを自動的にオーバーライドできます。 これにより、必要に応じて、推移的な依存関係が最上位の依存関係に暗黙的に昇格されます。

この機能を有効にするには、プロジェクトで、あるいはインポート ファイル Directory.Packages.props または Directory.Build.props で、MSBuild プロパティ CentralPackageTransitivePinningEnabledtrue に設定します。

<PropertyGroup>
  <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>

パッケージのバージョンをオーバーライドする

<PackageReference /> 項目の VersionOverride プロパティを使用して、個々のパッケージ バージョンをオーバーライドできます。 これにより、一元的に定義された <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>

この機能を無効にするには、プロジェクトで、あるいはインポート ファイル Directory.Packages.props または Directory.Build.props で、MSBuild プロパティ CentralPackageVersionOverrideEnabledfalse に設定します。

<PropertyGroup>
  <CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>

この機能を無効にした場合、いずれかの <PackageReference /> 項目で VersionOverride を指定すると、機能が無効であることを示すエラーが復元時に発生します。

Central Package Management を無効にする

特定のプロジェクトの Central Package Management を無効にする場合は、MSBuild プロパティ ManagePackageVersionsCentrallyfalseに設定して無効にできます。

<PropertyGroup>
  <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>

グローバル パッケージ参照を追加する

Note

この機能は、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>

複数のパッケージ ソースを使用するときの警告

Central Package Management を使用すると、構成で複数のパッケージ ソースが定義されている場合、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.

Note

中央パッケージマネージャーは、開発中です。 使ってみて、フィードバックを NuGet/Home にお寄せください。