使用基于 Roslyn 的 Microsoft.CodeAnalysis.PublicApiAnalyzers 来追踪项目的 API 改动,帮助保持库的 API 兼容性

2023-10-22 10:27:32 浏览数 (1)

做库的时候,需要一定程度上保持 API 的兼容性


第一步:安装 NuGet 包

首先打开你的库项目,或者如果你希望从零开始也可以直接新建一个项目。这里为了博客阅读的简单,我创建一个全新的项目来演示。

然后,为主要的库项目安装 NuGet 包:

  • NuGet Gallery - Microsoft.CodeAnalysis.PublicApiAnalyzers

安装完成之后,你的项目文件(.csproj)可能类似于下面这样:

1 2 3 4 5 6 7 8 9 10 11

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="2.9.3" /> </ItemGroup> </Project>

第二步:创建 API 记录文件

在你的项目内创建两个文件:

  • PublicAPI.Shipped.txt
  • PublicAPI.Unshipped.txt

这就是两个普通的文本文件。创建纯文本文件的方法是在项目上右键 -> 添加 -> 新建项...,然后在打开的模板中选择 文本文件,使用上面指定的名称即可(要创建两个)。

然后,编辑项目文件,我们需要将这两个文件加入到项目中来。

如果你看不到上图中的“编辑项目文件”选项,则需要升级项目文件到 SDK 风格,详见:

  • 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成 Sdk 风格的 csproj - walterlv

然后,将这两个文件添加为 AdditionalFiles

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="2.9.3" /> </ItemGroup> <ItemGroup> <AdditionalFiles Include="PublicAPI.Shipped.txt" /> <AdditionalFiles Include="PublicAPI.Unshipped.txt" /> </ItemGroup> </Project>

如果你把这两个文件放到了其他的路径,那么上面也需要改成对应的路径。

这时,这两个文件内容还是空的。

第三步:添加 API 记录

这个时候,你会看到库中的 public 类、方法、属性等都会发出修改建议,说此符号并不是已声明 API 的一部分。

点击小灯泡,即可将点击所在的 API 加入到 PublicAPI.Unshipped.txt 中。

我将两个 API 都添加之后,PublicAPI.Unshipped.txt 文件中现在是这样的(注意有一个隐式构造函数哦):

1 2 3

Walterlv.PackageDemo.ApiTracking.Class1 Walterlv.PackageDemo.ApiTracking.Class1.Class1() -> void Walterlv.PackageDemo.ApiTracking.Class1.Foo.get -> string

体验 API 的追踪

现在,我们将 Foo 属性改名成 Foo2 属性,于是就会出现编译警告:

RS0016 Symbol ‘Foo2.get’ is not part of the declared API. RS0017 Symbol ‘Walterlv.PackageDemo.ApiTracking.Class1.Foo.get -> string’ is part of the declared API, but is either not public or could not be found

提示 Foo2 属性不是已声明 API 的一部分,而 Foo 属性虽然是已声明 API 的一部分,但已经找不到了。

这种提示对于保持库的兼容性是非常有帮助的。

将警告变成错误

在分析器的规则上面右键,可以为某项规则设置严重性。

这时,再编译即会报告编译错误。

项目中也会多一个规则集文件:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <CodeAnalysisRuleSet>Walterlv.PackageDemo.ApiTracking.ruleset</CodeAnalysisRuleSet> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="2.9.3" /> </ItemGroup> <ItemGroup> <AdditionalFiles Include="PublicAPI.Shipped.txt" /> <AdditionalFiles Include="PublicAPI.Unshipped.txt" /> </ItemGroup> </Project>

第四步:将 API 打包

前面我们都是在 PublicAPI.Unshipped.txt 文件中追踪 API。但是如果我们的库需要发布一个版本的时候,我们就需要跟上一个版本比较 API 的差异。

上一个发布版本的 API 就记录在 PublicAPI.Shipped.txt 文件中,这两个文件的差异即是这两个版本的 API 差异。在一个新的版本发布后,就需要将 API 归档到 PublicAPI.Shipped.txt 文件中。


参考资料

  • roslyn-analyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md at master · dotnet/roslyn-analyzers

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/track-api-changes-using-roslyn-public-api-analyzers.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

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

0 人点赞