c# - 如何强制主机应用程序加载 .Net 插件版本的传递依赖项
问题描述
我正在开发一个 C# .NET Framework (4.7.2) 插件,但无法让宿主应用程序加载我的传递依赖项版本。该插件适用于 Revit 2020(也是 .NET 4.7.2),但我认为该问题对于 .Net 插件主机上下文是通用的。
特别是我正在尝试使用依赖于 Microsoft.Extensions.DependencyInjection.Abstractions(此处为 DI.Abstractions)的 Entity Framework Core 3。Revit 本身不依赖于 EF Core,如果确实如此,我可以使用它extern alias
来加载我想要的版本。但是,Revit 的一个组件确实依赖于旧版本的 DI.Abstractions (1.01...),而不是 EF Core (3.100...)。加载 EF Core 时,Revit 使用自己的 DI.Abstractions dll,这会导致“找不到方法”错误。还有几个其他的 dll 似乎有类似的问题,但如果我能找到一种方法来强制加载正确的 dll,我很确定我会为所有这些问题解决问题。
我尝试过的最值得注意的事情是,我在另一个项目中遇到了同样的问题,也使用了 Revit 中的 EF Core,通过使用 ILMerge 结合 Microsoft.Extensions.DependencyInjection(此处为 DI)和 DI.Abstractions。据我所知,因为 DI.Abstractions 只是从 DI 中引用,这使 Revit 无法知道 DI.Abstractions 的存在。但是在当前的项目中,这并没有奏效。我能看到的唯一区别是我使用 Sqlite 和 EF Core 而不是 MySql。大概是触发了其他一些依赖链,导致 DI.Abstractions 从另一个角度加载?
我尝试过的其他事情:
- 合并
- 我尝试合并整个插件,但 EF Core 使用了一些反射,如果它已使用 ILMerge 合并,则会中断。
- EF Core 的三个依赖项依次在其依赖项链中包含 DI.Abstractions。我尝试将这三个库中的每一个的所有依赖项合并到库本身中,就像我在上面对上面的 DI 所做的那样。DI.Abstractions 仍由 Revit 加载。
- AppDomain.AssemblyResolve:此事件允许处理程序找到 Revit 否则无法找到的 dll。我使用处理程序从插件文件夹加载一些 dll,但这里的问题是 Revit可以找到 dll,并且它使用了错误的。我的 AssemblyResolve 处理程序永远不会为 DI.Abstractions 触发。
这是发生错误时 VS 模块窗口的尾部(名称、路径和版本列)。您可以看到许多 dll 正在从 Revit 的文件夹中加载,并且版本为 1.01.2.30427。EF Core 想要(并且在 addin 文件夹中有)3.100.520.27007。
Microsoft.Data.Sqlite.dll
<Addin Path>\Microsoft.Data.Sqlite.dll
3.100.520.27007
AddinName.Database.dll
<Addin Path>\AddinName.Database.dll
1.00.0.20284
Microsoft.EntityFrameworkCore.dll
<Addin Path>\Microsoft.EntityFrameworkCore.dll
3.100.520.27007
Microsoft.Bcl.AsyncInterfaces.dll
<Addin Path>\Microsoft.Bcl.AsyncInterfaces.dll
4.700.20.21406
System.Threading.Tasks.Extensions.dll
<Addin Path>\System.Threading.Tasks.Extensions.dll
4.06.28619.1
AddinName.RevitUtils.dll
<Addin Path>\AddinName.RevitUtils.dll
1.00.0.20286
Microsoft.Extensions.DependencyInjection.Abstractions.dll
C:\Program Files\Autodesk\Revit 2020\Addins\FabricationPartBrowser\Microsoft.Extensions.DependencyInjection.Abstractions.dll
2.02.0.18315
System.ValueTuple.dll
C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.ValueTuple\v4.0_4.0.0.0__cc7b13ffcd2ddd51\System.ValueTuple.dll
4.08.3752.0
Microsoft.Extensions.DependencyInjection.dll
C:\Program Files\Autodesk\Revit 2020\Addins\FabricationPartBrowser\Microsoft.Extensions.DependencyInjection.dll
2.02.0.18315
Microsoft.Extensions.Logging.Abstractions.dll
C:\Program Files\Autodesk\Revit 2020\AddIns\PnIDModeler\Microsoft.Extensions.Logging.Abstractions.dll
1.01.2.30427
System.Diagnostics.DiagnosticSource.dll
<Addin Path>\System.Diagnostics.DiagnosticSource.dll
4.700.20.21406
Microsoft.EntityFrameworkCore.Abstractions.dll
<Addin Path>\Microsoft.EntityFrameworkCore.Abstractions.dll
3.100.520.27007
Microsoft.Extensions.Caching.Abstractions.dll
C:\Program Files\Autodesk\Revit 2020\AddIns\PnIDModeler\Microsoft.Extensions.Caching.Abstractions.dll
1.01.2.30427
AddinName.Styles.dll
<Addin Path>\AddinName.Styles.dll
1.00.0.20284
NetTopologySuite.dll
<Addin Path>\NetTopologySuite.dll
2.00.0.0
Microsoft.EntityFrameworkCore.Sqlite.dll
<Addin Path>\Microsoft.EntityFrameworkCore.Sqlite.dll
3.100.520.27007
Microsoft.EntityFrameworkCore.Relational.dll
<Addin Path>\Microsoft.EntityFrameworkCore.Relational.dll
3.100.520.27007
System.Transactions.dll
C:\WINDOWS\Microsoft.Net\assembly\GAC_64\System.Transactions\v4.0_4.0.0.0__b77a5c561934e089\System.Transactions.dll
4.8.3752.0 built by: NET48REL1
Microsoft.Extensions.Logging.dll
C:\Program Files\Autodesk\Revit 2020\AddIns\PnIDModeler\Microsoft.Extensions.Logging.dll
1.01.2.30427
System.Threading.Tasks.dll
C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Threading.Tasks\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Threading.Tasks.dll
4.08.3752.0
Microsoft.Extensions.Caching.Memory.dll
C:\Program Files\Autodesk\Revit 2020\AddIns\PnIDModeler\Microsoft.Extensions.Caching.Memory.dll
1.01.2.30427
Microsoft.Extensions.Options.dll
C:\Program Files\Autodesk\Revit 2020\AddIns\PnIDModeler\Microsoft.Extensions.Options.dll
1.01.2.30427
编辑我尝试过的另一件事。运行插件命令时(因此在加载有问题的 dll 之前),我循环浏览插件文件夹中的所有 dll 文件并使用Assembly.LoadFrom
. Revit 仍会从其自己的文件中加载和使用旧的 DI.Abstractions 等。我最终加载了两个版本的 dll,但使用的是旧版本而不是新版本。
解决方案
这是您已经尝试过的不同方法的令人印象深刻的列表。Afaik,Revit 仅支持AppDomain
将 .NET 库加载到其中的一个,因此我对您描述的一些部分成功感到惊讶。一种最终且保证成功的可能性是使用 IPC 进行解开,即,将您的加载项功能有问题的部分与在 Revit exe 中运行的主要加载项完全分开,并且只在外部独立部分和主要加载项之间进行通信 -在使用 IPC 来实现所需的功能。
推荐阅读
- javascript - 我收到一个错误,因为 Uncought 语法错误:标识符“i”已在我的 js 代码中声明
- angular - Ngx Bootstrap 下拉菜单无法在 ag 网格中显示完整列表
- linux - 在 vim 缩写中定义 linux 命令
- javascript - 无法更改源自 Android 原生基础的选取器元素的字体大小和字体粗细
- amazon-cloudformation - 如何在从控制台构建的现有服务上执行基础架构代码?
- python - 从 n m 列数据帧创建 m n 列数据帧
- r - 如何重新排列R中的列元素?
- java - 升级到 react-native 版本 0.60.4 后 react-native run-android 出错
- python - 在按钮单击时将线添加到 Plotly Scattermapbox
- kotlin - 如何在 okhttp 4 中使用新的扩展功能