微软近几年推出. NET Standard, 将. NET Framework,.NET Core,Xamarin 等目标平台的 api 进行标准化和统一化, 极大地方便了类库编写人员的工作. 简单的说, 类库编写人员在发布库的时候, 只需要基于. NET Standard 进行发布, 那么编写的程序可以在各个目标平台上都能到运行.
.NET Standard 是一种标准, 只要符合这个标准的平台都可以运行基于此标准 api 构建的程序.
感觉挺好用的, 但是实际上用起来就有一些坑了. 比如说这个常见的 FileNotFoundException, 当有这个情况的时候, 经常出现:
主程序的目标平台是某个具体平台 (不是. NET Standard, 比如说是. NET Framework 4.0), 随后为了引入新的特性, 升级了 Framework 为 4.6.1, 它并且引用了一个. NET Standard 类库, 恰好, 这个类库还引用了其他的 package.(即传递引用 A->B->C 的形式, 其中 A 是. NET Framework 程序, B 是 nuget 包, C 是 B 引用的 nuget 包.) 在此情况下, 如果 F5 启动程序, 就会报 FileNotFoundException.
测试条件
Visual Studio 2015 Community
测试用包: UnifiedConfig v1.1.6
提示未找到 System.IO.FileSystem. 乍看感觉是一个简单的引用错误, 但 unifiedconfig 包里面已经正常引用了这个项目, 按道理 vs 能够正常帮我们处理引用问题. 到文件输出路径中查看, 发现对应的包没有正确复制过来. 手动从 package 文件夹中复制过来, 问题解决.
原因出在这个跨平台上. 由于存在引用传递, B 不能确定需要复制哪个目标平台的 package 到 A 的输出路径. 当程序是从旧的 Framework 升级而来的时候, 旧版的项目文件不能很好地处理. NET Standard 的这个问题. 但我们手动一个一个复制也不是办法, 以下给出解决方案.
解决方案:
最直接的方案, 修改主项目的. csproj 文件, 将
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
添加到第一个 PropertyGroup
如果还不行, 加上
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
或者
在工具 ->nuget 包管理器 ->程序包管理 ->默认包管理格式, 从 Packages.config 改成 PackageReference.
后记
我记得在 visual studio 2017 早期版本还存在这个 bug, 升级之后 visual studio 2017 15.6.4 这个版本测试新建项目, 已经没有这个问题. 并且默认生成的基于 4.5.2 以上 Framework 的. csproj 文件已经添加
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
这个配置. 但是当老版本的项目引用. NET Standard 类库的时候, 还是经常会出现这个问题, 这时候, 就需要我们手动添加配置项目了.
来源: http://www.bubuko.com/infodetail-2586598.html