中央軟體套件管理 (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
則不需要。
開始
若要完整上線您的存放庫,請考慮採取下列步驟:
- 在名為
Directory.Packages.props
存放庫根目錄建立新檔案,以宣告您集中定義的套件版本,並將 MSBuild 屬性ManagePackageVersionsCentrally
設定為true
。 - 在
Directory.Packages.props
中宣告<PackageVersion />
項目。 - 在您的專案檔中聲明
<PackageReference />
項目,不含有Version
屬性。
如需中央套件管理外觀的概念,請參閱我們的 範例存放庫。
具遞移性釘選
即使沒有明確的最上層 <PackageReference />
,您也可以選擇加入稱為可轉移釘選的功能,來自動覆寫可轉移套件版本。 這會在必要時以隱含方式將可轉移的相依性提升至最上層相依性。
請注意,在轉移釘選套件時,允許降級。 如果您嘗試將套件固定在比相依性要求更低的版本,還原將會引發 NU1109 錯誤。
您可以透過在項目中或在 Directory.Packages.props
或 Directory.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.props
或 Directory.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提供任何意見反饋。