C# Azure SDK程序集绑定重定向失效问题求助
我正在为现有程序开发基于.NET Framework 4.6的DLL扩展,使用Azure SDK类库。程序开发人员已编译程序并引用我的DLL,但运行时发现程序同时尝试加载两个版本的Azure.Core:项目引用的1.42版本,以及Azure.ResourceManager NuGet包依赖的>=1.39对应的1.39版本。Azure.ResourceManager也有类似问题,同时加载1.12和1.13版本(推测由某个ResourceManager子模块引用)。原本预期绑定重定向能解决此问题,让运行时仅加载指定版本,但未生效。
已尝试的操作:
- 将所有类库放入扩展构建文件夹及程序可执行文件所在目录
- 反复检查app.config,确认绑定重定向已启用且配置正确(包含公钥),并多次重新编译
- 将绑定重定向配置添加到计算机的machine.config中
- 在另一台安装相同程序的计算机上运行,问题依旧
- 更换Azure.Core/Azure.ResourceManager的DLL版本,错误中的版本也随之切换
目前已无其他排查思路。
补充app.config内容:
<?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.9" newVersion="6.0.0.9" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Security.Cryptography.ProtectedData" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Azure.Core" publicKeyToken="92742159e12e44c8" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.42.0.0" newVersion="1.42.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.1" newVersion="6.0.0.1" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Azure.ResourceManager" publicKeyToken="92742159e12e44c8" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.13.0.0" newVersion="1.13.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup></configuration>
确认主程序配置文件生效
绑定重定向规则必须写入主程序的.exe.config,而非你的DLL扩展的配置文件。如果开发人员仅引用了你的DLL,你的app.config不会自动合并到主程序配置中,需手动将绑定重定向节点复制到主程序的配置文件内。启用自动生成绑定重定向
在主程序的.csproj项目文件中添加以下配置,让Visual Studio自动处理依赖版本冲突,避免手动配置遗漏:<PropertyGroup> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> </PropertyGroup>重新编译主程序后,检查生成的.exe.config是否包含正确的重定向规则。
查看程序集加载日志
使用Fusion Log Viewer(fuslogvw.exe)追踪程序集加载细节,确认绑定重定向是否被实际应用:- 以管理员身份运行fuslogvw.exe
- 勾选“启用程序集绑定失败日志”并设置日志目录
- 运行程序后,查看重复加载或加载失败的程序集日志,确认重定向规则是否被忽略
统一Azure SDK子模块依赖版本
Azure.ResourceManager的子模块可能直接引用了特定版本的依赖,未继承主版本的重定向规则。可通过两种方式处理:- 在你的扩展项目中,直接安装所有相关Azure.ResourceManager子模块,并指定与主版本一致的版本号,强制统一依赖
- 使用NuGet包管理器的“管理解决方案的NuGet程序包”功能,将所有项目中的Azure.Core和Azure.ResourceManager版本统一为你指定的版本
验证部署的DLL版本
检查部署到目录中的DLL文件实际版本,右键DLL→属性→详细信息,确认版本号与绑定重定向中newVersion指定的完全一致,避免部署错误版本的文件。通过AssemblyResolve事件强制加载指定版本
如果以上方法均无效,可在主程序或你的扩展中添加程序集解析事件,手动指定加载的目标版本:AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var assemblyName = new AssemblyName(args.Name); if (assemblyName.Name == "Azure.Core" && assemblyName.Version < new Version(1,42,0,0)) { return Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Azure.Core.dll")); } if (assemblyName.Name == "Azure.ResourceManager" && assemblyName.Version < new Version(1,13,0,0)) { return Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Azure.ResourceManager.dll")); } return null; };
内容的提问来源于stack exchange,提问作者Amaranth96

