自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference

自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference

发布于 2018-04-24 10:03 更新于 2018-06-29 08:52

在前段时间我写了一篇迁移 csproj 格式的博客 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj,不过全过程是手工进行的,而且到最后处理 XAML 问题也非常头疼。

现在,我们可以利用工具自动地完成这个过程。当然,工具并不将 csproj 格式进行迁移,而是在不迁移格式的情况下,使用到 PackageReference 方式 NuGet 引用带来的好处。


自动升级

下载安装 Visual Studio 插件 NuGet PackageReference Upgrader。在安装完成之后,再次启动 Visual Studio,则可以开始迁移。

只有一个步骤:在 packages.config 文件上点击右键,选择 Upgrade to PackageReference

紧接着,稍微等待一下,即可完成一个项目的迁移。如果有多个项目,则每个项目都这么操作即可。

相比于之前写的手工迁移,自动迁移方式没有改变 csproj 的格式,而只是将 NuGet 的引用方式改成了 PackageReference。具体有哪些好处,可以阅读 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj

检查升级后的兼容性问题

packages.config 的 NuGet 包的管理方式有些功能是 PackageReference 没有的。当然,没有这些功能是因为“不需要”,而不是“还没支持”;所以大部分的迁移都不会发生问题(除非发布包使用的是特别老旧的 nuget.exe,或者发布者利用了一些丧心病狂的黑科技)。

install.ps1 脚本将失效

使用 PackageReference 后,在安装和写在的过程中 install.ps1 脚本将不再执行。如果有一些行为依赖于此脚本,那么这个 NuGet 包的行为可能不正常。

但是,不用担心!install.ps1 的存在是因为 packages.config 不支持 PackageReference 中的一些新特性(例如 NuGet 包中新的目录结构,例如包中自带的 msbuild targets)。所以,如果 NuGet 包在发布时满足目录要求,那么即便 install.ps1 不用执行也能保证包的行为正常。

使用 content 方式指定的内容资产将失效

PackageReference 使用 contentFiles 来管理内容资产,这样可以更好地在多个依赖包之间传递和共享。而此前 content 指定的资产将失效。

建议检查所有依赖的 NuGet 包,如果你有权限修改部分依赖包,那么请使用 contentFiles 来替代 content

XDT 变换将失效

使用 PackageReference 后,在安装和写在的过程中 XDT 转换将不会执行,并且会忽略 .xdt 文件。

在 Web 应用开发中会更留意这个问题。

lib 根目录中的程序集将被忽略

lib 文件夹内的程序集都应该按照目标框架建立子文件夹,例如 net45、netstandard2.0、netcoreapp2.0。PackageReference 要求只能引用在某个目标框架下的程序集。

如果是使用默认的方式创建的 NuGet 包,基本上不会遇到这样的问题。除非你在创建 NuGet 包时有自定义操作在根目录放了程序集。

解决升级后的编译错误

最可能出现的编译问题是 NuGet 包引用的版本冲突。

packages.config 方式的包引用要求在 csproj 文件中显式指定一个依赖的包的版本,于是无论依赖使用了哪个版本,最终都由显式指定的版本来指定。

PackageReference 的引用方式是自动管理依赖版本的,只要每个包都在允许的版本范围之内,就自动选择版本,并显示在解决方案的引用中。

PackageReference 出现依赖冲突的提示通常是这样的:

Version conflict detected for NuGet.Versioning. Reference the package directly from the project to resolve this issue.
NuGet.Packaging 3.5.0 -> NuGet.Versioning (= 3.5.0)
NuGet.Configuration 4.0.0 -> NuGet.Versioning (= 4.0.0)

也就是说,引用的两个不同的包要求依赖相同包的不同版本,于是 PackageReference 无法隐式推断依赖包的版本。这时需要将项目的依赖方式改为之前的方式。

当然,在制作和发布 NuGet 包时,尽量使用非特定版本的依赖包,能够极大地避免这种问题带来的影响。关于如何指定非特定版本的依赖包,可以阅读 Version ranges and wildcards 版本范围和通配符


参考资料

本文会经常更新,请阅读原文: https://walterlv.com/post/migrate-packages-config-to-package-reference.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏walterlv - 吕毅的博客

如何最快速地将旧的 NuGet 包 (2.x, packages.config) 升级成新的 NuGet 包 (4.x, PackageReference)

发布于 2018-05-13 09:07 更新于 2018-06...

6610
来自专栏小白课代表

编程 | VC++ 6.0 (WIN10可用)安装教程

39130
来自专栏GuZhenYin

SignalR系列续集[系列8:SignalR的性能监测与服务器的负载测试]

前言 也是好久没写博客了,近期确实很忙,嗯..几个项目..头要炸..今天忙里偷闲.继续我们的小系列.. 先谢谢大家的支持.. 我们来聊聊SignalR的性能监测...

26160
来自专栏图像识别与深度学习

Android学期项目指导

20550
来自专栏施炯的IoT开发专栏

Windows 10 IoT Serials 8 – 如何改变UWP应用的目标平台

    Windows Insider计划直接加速了Windows系统的迭代,缩短了系统发布的周期。就Windows 10 IoT Core而言,迭代的速度和W...

19470
来自专栏FreeBuf

如何利用日志来监控和限制PowerShell攻击活动

写在前面的话 近期,我一直在我客户的网络环境中分析PowerShell攻击,根据我的分析以及研究结果,我发现了几种方法来帮助研究人员检测潜在的PowerShel...

26450
来自专栏张善友的专栏

.NET Web 自动化测试工具

Inspired by Watir development of WatiN started in December 2005 to make a simila...

21390
来自专栏张善友的专栏

Windows Server AppFabric正式发布

Windows Server AppFabric 是一组集成技术,可更轻松地生成、扩展和管理 IIS 上运行的 Web 应用程序和复合应用程序,它是一款主要面向...

21580
来自专栏逆向技术

win32之进程概念

  学习WindowsAPI. 之前.我们必须理解什么是进程. 在windows环境下.进程就是一个运行起来的exe程序

9920
来自专栏walterlv - 吕毅的博客

帮助官方 NuGet 解掉 Bug,制作绝对不会传递依赖的 NuGet 包

发布于 2018-08-05 13:22 更新于 2018-08...

9520

扫码关注云+社区

领取腾讯云代金券