dotnet 根据基线包版本实现库版本兼容-C/S开发框架
本文来告诉大家如何根据 基线包版本 的功能来实现自动在构建过程中,告诉开发者,当前版本是否存在不兼容旧版本的变更。其不兼容变更包括二进制中断变更和 API 不兼容变更和源代码中断变更。可以让库开发者花更少的精力在测试兼容性上 今天看到了队长推送的 .NET 6新特性试用 Nuget包验证 博客,才回忆起此功能。这个功能是给库和框架开发者使用的,用于处理多版本兼容性问题 背景只有对一个库或框架准备对外发布且长期维护,以及期望给其他开发者使用时,才需要考虑库或框架的兼容性问题。越是开发底层的库,兼容性问题就越加重要。此重要性,只有自己参与开发,踩够坑之后,才能有所体会 换句话说,判断一位开发者是不是库或框架的老司机开发者,可以通过他的兼容性处理上来看出。哈哈,需要说明的是,不是所有老司机开发者都是库或框架开发方向的,这是判断有经验的开发者的充分不必要条件 开始之前,先聊聊什么是兼容性问题。兼容性可以分为以下不兼容变更:
此外,还有更换了底层运行时框架的变更等,但这些就不在本文讨论范围了 更多请参阅官方文档的详细描述: 重大更改和 .NET 库 Microsoft Docs 对于使用库或框架的开发者来说,一方面又期望用上新版本的强大功能,另一方面又怕有不兼容的变更,需要花费大量的精力在更新上面。如果库或框架的开发者,可以保持好兼容性,那么升级版本是一个很轻松的事情 对于咱 dotnet 系的大部分库或框架开发者来说,在开发过程中,考虑兼容性是一个必备的选项。那如果真的需要变更 API 了呢?问题也不大,别忘了咱还有版本号规则 版本号规则基本所有 dotnet 系上,正经的库和框架都会遵循约定的版本号规则,从而让开发者在使用任何库的时候,通过版本号都能明确其中的含义,决定自己是否应该升级到最新版本 无异议的版本规则是,版本号由四个部分组成,分为
此外,有一些库毕竟激进,需要发布预览版本等,可以考虑采用语义版本号的方法,请看 语义版本号(Semantic Versioning) - walterlv - cscode.net 通过如上的说明,可以了解到,如果不想刷主版本号,那就要求库或框架保持兼容旧版本。兼容旧版本需要在开发时,投入精力了解是否存在不兼容的更改,然而纯依靠手动去阅读代码了解是否存在不兼容的变更,当然是不靠谱的。本文将告诉大家如何使用 使用方法一如既往的简单,只需要在项目文件上,添加如下代码即可
例如当前是 2.0.0 的版本,期望进行对 1.0.0 包版本的兼容性测试,可以将 PackageValidationBaselineVersion 的值更改为 1.0.0 版本,如下面代码
如此,在存在中断性(也就是不兼容,需要代码适配)变更时,在会在构建时给出提示,同时让构建不通过 例子如何更好的使用此功能,还请让我用一个例子来告诉大家。此例子完全从 官方文档 抄的 在第一个版本时,作为 1.0.2 的版本的 NuGet 包,已对外发布。在进行 1.1.0 版本开发时,期望能做到完全的兼容第一个版本。利用 PackageValidationBaselineVersion 的功能,在 csproj 项目文件上,加上如下代码
通过在 PackageValidationBaselineVersion 执行定了基线包版本为 1.0.2 即可采用此指定的版本进行基线包版本对比。例如几周后,你的任务是为库添加对连接超时的支持,代码的
由于连接超时是一个高级配置设置,因此你认为可以添加一个可选参数,更改如下:
更改之后,构建过程可以正常,但是在打包的时候,将会收到如下提示,打包失败
或者中文版本的提示如下
如此通过打包失败,提示的 CP0002 失败,可以了解到,自己没有做到让当前版本对写入到 PackageValidationBaselineVersion 的兼容。此时要做的事情,要么是废弃掉对 PackageValidationBaselineVersion 的兼容,也就是删除此属性,同时升级主版本号,告诉其他开发者,当前版本存在不兼容。要么是更改 API 定义,更改到兼容 例如以上的代码,虽然加上了一个默认参数,可以实现到源代码兼容。但是大家都知道,这是二进制不兼容的,如果直接替换 DLL 文件,而不经过编译,将会在运行的过程中,因为找不到对应的方法而失败 什么情况下会遇到没有重新构建,只是替换 DLL 文件而已?在于是其他底层库的依赖引用,例如再有另一个库 C 也引用了此,而库 C 打出的 NuGet 包被最终项目所引用。当最终项目升级版本时,由于 Connect 方法被更改,从而让库 C 里面的对应逻辑找不到方法,而在运行时失败 因此为了做到这部分的兼容,可以考虑作为重载的方法更改,更改如下
这样进行重新打包,即可看到打包成功,兼容 PackageValidationBaselineVersion 的 1.0.2 版本 原理此功能是依托于 NuGet 包发布而拿到指定版本号规则的,和 使用基于 Roslyn 的 Microsoft.CodeAnalysis.PublicApiAnalyzers 来追踪项目的 API 改动,帮助保持库的 API 兼容性 - walterlv 的方法是完全不相同的 本文介绍的方法,是在 PackageValidationBaselineVersion 里面,声明的包版本,在构建过程中,通过 NuGet 去拉取对应的版本,接着通过 DLL 导出类型的对比,从而了解是否存在不兼容的变更 也就是说在 PackageValidationBaselineVersion 里面写入的版本号,要求是可以在 NuGet 源里面(无论是 nuget.org 源,还是你的私有的源,还是你的本机文件夹都可以)拉到对应的版本。由此版本里面的 DLL 执行具体的对比逻辑。这也就要求了此功能只能用在简单的 NuGet 上,对于很多上了黑科技的 NuGet 包是无法执行的。例如使用 SourceYard 打包的源代码包 本文介绍的方法,对比使用基于 Roslyn 的 Microsoft.CodeAnalysis.PublicApiAnalyzers 来追踪项目的 API 改动,帮助保持库的 API 兼容性 的方法来说,优势在于不需要带上 代码可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源
获取代码之后,进入 NallcearreyiHernareferkear 文件夹
参考文档:
C/S开发框架标准版有版本自动升级功能吗? C/S开发框架的数据访问层用LINQ吗? C/S开发框架标准版-后台数据更新流程图(例子) C/S开发框架是如何授权的?有没有基于角色的权限控制? C/S开发框架中讲到的ADO Direct是什么? C/S开发框架Toolbar按钮的动态生成与调用关系 C/S开发框架代码生成器工具增加DevExpress版本配置 C/S开发框架新功能:批量更新业务单据的业务员、制单人制表人 百度地图API应用 - 根据地址查询经纬度-C/S开发框架 Visual Studio 2019 (C#/.NET)安装教程-C/S开发框架 ChartControl图表组件ArgumentScaleType/ValueScaleType轴的刻度类型-C/S开发框架 采购部评估:市场C/S架构快速开发框架软件对比(doc文档下载)-C/S开发框架 C#.NET其他程序集访问Internal类-C/S开发框架 理解C#.NET泛型运作原理-C/S开发框架 C#使用PInvoke.Kernel32加载非托管DLL嵌入资源-C/S开发框架
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 | |