中央包管理 (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
。
然后,在其中使用定义包 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 />
项。 - 在项目文件中声明不带
Version
属性的<PackageReference />
项。
若要了解中央包管理可能是什么样子,请参阅示例存储库。
可传递固定
即使没有显式的顶级 <PackageReference />
,你也可以选择称为可传递固定的功能来自动替代可传递包版本。 这样可在必要时代表你将可传递依赖项隐式地提升为顶级依赖项。
可通过在项目中或在 Directory.Packages.props
或 Directory.Build.props
导入文件中将 MSBuild 属性 CentralPackageTransitivePinningEnabled
设置为 true
来启用此功能:
<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 属性 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 上体验并提供任何反馈。