NuGet包含AssemblyBinding原因及Azure.Storage.Queues版本冲突疑问
我正在使用Azure.Storage.Queues NuGet包,发现它附带了assemblyBinding配置,此前对此并不了解。最初用该包构建.NET Standard 2.0类库,通过CopyLocalLockFileAssemblies发布项目引用的所有程序集。执行代码:
Azure.Storage.Queues.QueueClient.SendMessageAsync("someMessage",default);
时,持续报错:
Could not load file or assembly 'System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
Visual Studio显示Azure.Storage.Queues包依赖System.Buffers 4.5.1 NuGet包,其包含System.Buffers.dll v4.0.3.0程序集,但运行时却尝试加载System.Buffers.dll v4.0.2.0。在类库项目中无法排查此问题,直到将该包导入控制台应用时,发现它更新了App.config文件才意识到存在绑定配置。另外,System.Buffers 4.5.1包的ref文件夹包含System.Buffers.dll v4.0.2.0,lib文件夹包含System.Buffers.dll v4.0.3.0。
疑问
- NuGet包中是否有标识表明其需要assemblyBinding配置?
- 为何
Azure.Storage.Queues.QueueClient.SendMessageAsync方法尝试使用System.Buffers.dll v4.0.2.0版本?
1. NuGet包中是否有标识表明其需要assemblyBinding配置?
有两种直观的判断方式:
- 查看包内的build文件:需要绑定配置的包通常会在
build目录下包含.props或.targets文件,这些文件里会定义自动将绑定重定向配置注入到项目的App.config/Web.config的逻辑,Azure SDK类的包大多采用这种方式。 - 观察依赖包的版本差异:如果NuGet包依赖的程序集,其编译引用版本(ref目录)和运行时实际版本(lib目录)不一致,基本可以确定需要通过assemblyBinding来解决版本匹配问题。
2. 为何SendMessageAsync尝试加载System.Buffers v4.0.2.0?
核心原因是编译与运行时的引用版本不一致:
- 编译阶段,项目引用的是NuGet包
ref目录下的引用程序集,这个程序集只包含元数据,版本为v4.0.2.0,因此生成的IL代码中会记录需要加载该版本的System.Buffers。 - 运行阶段,实际部署的是
lib目录下的运行时程序集,版本为v4.0.3.0,但CLR默认会按照编译时记录的版本标识去查找,这就导致了版本不匹配的错误。此时需要assemblyBinding配置(绑定重定向),告知运行时将对v4.0.2.0的请求重定向到v4.0.3.0。
内容的提问来源于stack exchange,提问作者Bijaya Rai

