Openedge中bindingRedirect对C# DLL失效问题求助
解决Openedge加载依赖System.Runtime.CompilerServices.Unsafe V6.0.0的C# DLL绑定失败问题
针对你遇到的Openedge加载DLL时的程序集绑定冲突问题,以下是几个无需操作GAC的可行解决方案:
1. 合并依赖程序集到主DLL
通过工具将System.Runtime.CompilerServices.Unsafe V6.0.0直接合并到你的业务DLL中,彻底消除外部依赖文件的版本冲突问题:
- 使用Costura.Fody:这是NuGet上的常用工具,安装后无需复杂配置,编译时会自动将指定依赖嵌入主程序集。
- 在你的DLL项目中安装NuGet包
Costura.Fody - 编译项目后,生成的DLL会包含
System.Runtime.CompilerServices.Unsafe的代码,无需单独携带该依赖文件
- 在你的DLL项目中安装NuGet包
- 或使用ILMerge:命令行工具,手动指定主DLL和依赖DLL进行合并,适合需要精确控制合并过程的场景。
2. 手动处理程序集解析事件
在你的DLL初始化阶段注册AssemblyResolve事件,当Openedge尝试加载其他版本的System.Runtime.CompilerServices.Unsafe时,强制返回你提供的V6.0.0版本:
using System; using System.Reflection; using System.IO; public static class AssemblyResolver { public static void Initialize() { AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; } private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) { var assemblyName = new AssemblyName(args.Name); // 匹配目标依赖名称 if (assemblyName.Name.Equals("System.Runtime.CompilerServices.Unsafe", StringComparison.OrdinalIgnoreCase)) { // 获取当前DLL所在目录 var currentAssemblyPath = Assembly.GetExecutingAssembly().Location; var currentDir = Path.GetDirectoryName(currentAssemblyPath); // 构造依赖DLL的路径 var unsafeDllPath = Path.Combine(currentDir, "System.Runtime.CompilerServices.Unsafe.dll"); if (File.Exists(unsafeDllPath)) { return Assembly.LoadFrom(unsafeDllPath); } } return null; } }
在你的DLL被Openedge加载后,先调用AssemblyResolver.Initialize()方法注册事件,后续依赖解析会自动使用你指定的版本。
3. 为Openedge主进程添加绑定重定向配置
如果Openedge使用固定的主程序(如proenv.exe或自定义加载器),可以将绑定重定向配置添加到该主程序对应的.config文件中:
<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> </assemblyBinding> </runtime> </configuration>
将上述配置保存为[Openedge主程序名].config,放到主程序所在目录。这种方式需要确认Openedge主程序会读取对应的配置文件,适合对Openedge部署环境有一定控制权的场景。
4. 使用NuGet包的"PrivateAssets"配置(针对开发阶段)
在你的DLL项目中,将System.Runtime.CompilerServices.Unsafe的NuGet包PrivateAssets设为all,确保编译时该依赖会被复制到输出目录,且不会向上传递依赖:
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0"> <PrivateAssets>all</PrivateAssets> </PackageReference>
这能确保打包MSI时该依赖文件被正确包含到安装目录中,配合前面的方案使用效果更好。
内容的提问来源于stack exchange,提问作者CephDigital
相关产品推荐
相关产品推荐

