共用方式為


中央軟體套件管理 (CPM)

相依性管理是 NuGet 的核心功能。 管理單一專案的相依性很容易。 管理多專案解決方案的相依性可能非常困難,因為它們的規模和複雜性開始增加。 在管理許多不同專案的一般相依性的情況下,您可以利用 NuGet 的中央套件管理 (CPM) 功能,從單一位置輕鬆完成這一切。

歷史上,NuGet 套件的相依性通常在兩個位置之一被管理:

  • packages.config - 舊版項目類型中使用的 XML 檔案,用來維護專案所參考的套件清單。
  • <PackageReference /> - MSBuild 專案中所使用的 XML 元素會定義 NuGet 套件相依性。

NuGet 6.2開始,您可以使用新增 Directory.Packages.props 檔案和 MSBuild 屬性,集中管理專案中的相依性。

從下列版本開始,此功能適用於所有 NuGet 整合式工具。

較舊的工具將會忽略中央套件管理組態和功能。 若要充分利用此功能,請確定您的所有組建環境都使用最新的相容工具版本。

只要使用相容的工具,中央套件管理會套用至所有以 <PackageReference>為基礎的 MSBuild 專案(包括 舊版 CSPROJ)。

啟用中央套件管理

若要開始使用中央套件管理,您必須在存放庫根目錄建立 Directory.Packages.props 檔案,並將 MSBuild 屬性 ManagePackageVersionsCentrally 設定為 true

您可以手動建立它,或使用 dotnet CLI:

dotnet new packagesprops

接著,您將使用定義套件 ID 和版本的 <PackageVersion /> 元素,來定義您的專案所需的各個套件版本。

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

針對每個專案,您接著會定義 <PackageReference />,但省略 Version 屬性,因為版本將從對應的 <PackageVersion /> 專案取得。

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

現在,您正在使用中央套件管理,並在中央位置管理您的版本!

中央套件管理規則

Directory.Packages.props 檔案在存放庫目錄中的位置及其相關上下文有多項規則。 為了簡單起見,只會針對指定的項目評估一個 Directory.Packages.props 檔案。

這表示,如果您在存放庫中有多個 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,而只會為您匯入最接近專案的第一個。 如果您有多個 Directory.Packages.props,則必須手動匯入父項,而根 Directory.Packages.props 則不需要。

開始

若要完整上線您的存放庫,請考慮採取下列步驟:

  1. 在名為 Directory.Packages.props 存放庫根目錄建立新檔案,以宣告您集中定義的套件版本,並將 MSBuild 屬性 ManagePackageVersionsCentrally 設定為 true
  2. Directory.Packages.props中宣告 <PackageVersion /> 項目。
  3. 在您的專案檔中聲明 <PackageReference /> 項目,不含有 Version 屬性。

如需中央套件管理外觀的概念,請參閱我們的 範例存放庫

具遞移性釘選

即使沒有明確的最上層 <PackageReference />,您也可以選擇加入稱為可轉移釘選的功能,來自動覆寫可轉移套件版本。 這會在必要時以隱含方式將可轉移的相依性提升至最上層相依性。 請注意,在轉移釘選套件時,允許降級。 如果您嘗試將套件固定在比相依性要求更低的版本,還原將會引發 NU1109 錯誤。

您可以透過在項目中或在 Directory.Packages.propsDirectory.Build.props 匯入檔案中將 MSBuild 屬性 CentralPackageTransitivePinningEnabled 設定為 true 來啟用此功能:

<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>

因此,撰寫連結庫時,應該仔細評估使用可轉移釘選,因為這可能會導致您沒想到的相依性。

覆寫套件版本

您可以使用 <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.propsDirectory.Build.props 匯入檔案中將 MSBuild 屬性 CentralPackageVersionOverrideEnabled 設定為 false 來停用此功能。

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

停用此功能時,在任何 <PackageReference /> 專案上指定 VersionOverride 會導致還原時間發生錯誤,指出功能已停用。

停用中央套件管理

如果您想要停用任何特定專案的中央套件管理,您可以將 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 警告。 若要解決此警告,請透過 套件來源對應來設定套件來源,或指定單一套件來源。

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.

注意

集中套件管理正在積極開發中。 我們感謝您試用,並在 NuGet/Home提供任何意見反饋。