首页 > 解决方案 > 如何强制主机应用程序加载 .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 从另一个角度加载?

我尝试过的其他事情:

这是发生错误时 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,但使用的是旧版本而不是新版本。

标签: c#.netentity-framework-corerevitef-core-3.1

解决方案


这是您已经尝试过的不同方法的令人印象深刻的列表。Afaik,Revit 仅支持AppDomain将 .NET 库加载到其中的一个,因此我对您描述的一些部分成功感到惊讶。一种最终且保证成功的可能性是使用 IPC 进行解开,即,将您的加载项功能有问题的部分与在 Revit exe 中运行的主要加载项完全分开,并且只在外部独立部分和主要加载项之间进行通信 -在使用 IPC 来实现所需的功能。


推荐阅读