NuGet 新特性 -- 中心化的 NuGet 包版本管理
Intro
NuGet 支持了一个可以中心化管理 NuGet 包版本的方案,我们可以在一个地方统一管理 NuGet 包的版本
Preface
在之前的版本中我们通常在每个指定包版本引用的地方会设置 NuGet 包的版本号,如果项目比较多,一个解决方案中有很多个项目的时候,很多时候就会出现重复的包版本配置
有些项目中会使用变量来管理某些包的版本,定义变量来管理包版本,包引用处使用变量来指定包版本
而 NuGet 终于推出了一种集中管理包版本的方案,我们可以将统一的包版本定义在一个 Directory.Packages.props
文件中,在项目文件中就不需要再指定版本了,统一使用统一定义的 NuGet 包版本,这样更新包版本只需要更新这一个文件即可
Directory.Packages.props
Directory.Packages.props
和之前介绍过的 Directory.Build.props
有些类似,项目会寻找最近的一个 Directory.Packages.props
如下所示的项目结构:
Repository|-- Directory.Packages.props|-- Solution1|-- Directory.Packages.props|-- Project1|-- Solution2|-- Project2
Project1会使用
Repository\Solution1\
目录下的Directory.Packages.props
Project2 会使用
Repository\
目录下的Directory.Packages.props
Directory.Packages.props
内容示例:
<Project><ItemGroup><PackageVersion Include="Newtonsoft.Json" Version="13.0.1" /></ItemGroup>
</Project>
需要使用 PackageVersion
来定义中心化管理的包版本,对应项目中不能再包含 Version
定义了
当需要在项目文件中 override 某个包版本的时候可以使用 VersionOverride
指定要使用的版本,你可以通过定义一个 MsBuild 属性来禁用这一功能 <EnablePackageVersionOverride>false</EnablePackageVersionOverride>
Sample
来看一个使用的示例:
Directory.Packages.props
<Project><PropertyGroup><!-- Enable central package management --><ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally></PropertyGroup><ItemGroup><PackageVersion Include="JsonSchema.Net" Version="2.3.0" /><PackageVersion Include="MathNet.Numerics.Signed" Version="5.0.0" /><PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" /><PackageVersion Include="System.CommandLine" Version="2.0.0-beta3.22114.1" /><PackageVersion Include="WeihanLi.Common" Version="1.0.51" /><PackageVersion Include="WeihanLi.Npoi" Version="2.1.0" /> </ItemGroup><ItemGroup><PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.1.0" /><PackageVersion Include="FluentAssertions" Version="6.6.0" /><PackageVersion Include="Moq" Version="4.17.2" /><PackageVersion Include="xunit" Version="2.4.1" /><PackageVersion Include="Xunit.DependencyInjection" Version="8.5.0" /><PackageVersion Include="xunit.runner.visualstudio" Version="2.4.3" /><PackageVersion Include="coverlet.collector" Version="3.1.2" /></ItemGroup>
</Project>
项目文件示例:
<Project> <ItemGroup><PackageReference Include="JsonSchema.Net" /><PackageReference Include="MathNet.Numerics.Signed" /><PackageReference Include="Microsoft.Extensions.Logging.Console" /><PackageReference Include="System.CommandLine" /><PackageReference Include="WeihanLi.Common" /><PackageReference Include="WeihanLi.Npoi" /></ItemGroup>
</Project>
代码变更:
https://github.com/WeihanLi/dotnet-httpie/commit/a3ece1242e4edd83da36b195cd2859042dae0b5c
More
使用这一功能我们可以更方便的管理我们项目中的 NuGet 包版本,目前还没有默认启用需要等下一个版本的 SDK 发布,现在使用需要显式声明 <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
,下个版本就会默认支持,不再需要显式声明了,如果你要禁用则声明为 false
即可,目前的 SDK 中还是一个 preview feature,但是已经可用
如果同时使用多个 NuGet 源,同一个 package 存在于多个源中,则会遇到一个 NU1507
的 warning,可以结合 Package Source Mapping 来指定 package 要使用源,nuget.config 示例:
<!-- Define the package sources, nuget.org and contoso.com. -->
<!-- `clear` ensures no additional sources are inherited from another config file. -->
<packageSources><clear /><!-- `key` can be any identifier for your source. --><add key="nuget.org" value="https://api.nuget.org/v3/index.json" /><add key="contoso.com" value="https://contoso.com/packages/" />
</packageSources><!-- Define mappings by adding package patterns beneath the target source. -->
<!-- Contoso.* packages will be restored from contoso.com, everything else from nuget.org. -->
<packageSourceMapping><!-- key value for <packageSource> should match key values from <packageSources> element --><packageSource key="nuget.org"><package pattern="*" /></packageSource><packageSource key="contoso.com"><package pattern="Contoso.*" /></packageSource>
</packageSourceMapping>
References
https://devblogs.microsoft.com/nuget/introducing-central-package-management/
https://github.com/NuGet/Samples/pull/52
https://docs.microsoft.com/en-us/nuget/consume-packages/central-package-management
https://docs.microsoft.com/zh-cn/nuget/consume-packages/package-source-mapping
https://github.com/WeihanLi/dotnet-httpie/commit/a3ece1242e4edd83da36b195cd2859042dae0b5c