首页 > 解决方案 > 从插件加载具有相同 AssemblyVersion 的多个.net 程序集

问题描述

我在dll地狱。

我正在为一个名为 ANSYS 的庞大、古老且非常强大的软件套件构建一个插件。他们有一个插件框架。我曾希望他们能通过AssemblyContexts 或AppDomains 或其他一些我不理解的聪明的 dotnet 设备为我神奇地处理一切。他们不。

结果是我通过 nuget 创建了一个依赖于 GRPC.core 1.16.0 的应用程序。我写了一个小应用程序,用一个 winform 主机驱动我的插件。它加载并完美运行,在~/myproject/bin/debug/grpc.core.1.1.16.dll我的插件类库旁边找到我的库,没问题。

当我在 ANSYS 进程空间中运行我的插件时,它恰好也依赖于 grpc 1.0.0.0,链接器发现C:\Program FIles\ANSYS\...\WIN64\grpc.core.dll. 不好。

关于 Nuget GRPC 包的一件奇怪的事情是,它添加了一个“参考版本”为 1.0.0.0 的参考,其中大多数其他 nuget 包的参考版本与 nuget 包版本匹配。如果我手动更改参考版本,编译器将找不到该库。

<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad">
  <HintPath>..\packages\Grpc.Core.1.16.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>

编辑:关键在上面一行。Nuget 发布的 Grpc.core 工件位于AssemblyInformationVersion=1.16.1.0, AssemblyFileVersion=1.16.1.0, AssemblyVersion=1.0.0.0. 我将此记录为对 GRPC 的请求。更多如下。

因此,我需要告诉运行时链接工具不要使用在 ANSYS 自己的二进制目录中找到的 grpc.core...dll 更重要的是,我希望从我的父进程上下文中加载一个 dll(及其依赖项):那就是ANSYS API dll 本身,可能已经在 GAC 中。在我的项目中,我将此作为非 nuget 引用包含在其中,并选择了“构建操作:请勿复制”。

所以我的问题:

  1. 我可以在运行时做一些简单易行的事情来告诉运行时链接器“当有人从你认为应该是的程序集中加载类型时grpc.core,不要加载 1.0.0.0,准确地找到 1.16.0.0”?

    运行时已经通过“强名称”匹配所需的库。问题是 1.16.0 用词不当。该版本字符串是信息性的,但程序集本身是版本 1.0.0.0。Fusion 已经通过完全匹配加载了我想要的库。

  2. 我可以用 appdomains 或上下文或其他 C# 设备做一些更聪明的事情来显式地进入某种嵌套范围吗?我可以把它记录为 ANSYS API 中的错误吗?

我自己尝试过深入研究,但我不是 dotnet 专家,我不是在查看我是否正在查看与我无关的 nuget 包配置选项,还是老式的 dotnet 运行时选项,一直很棘手。


更新1:

我试过使用AppDomain.CreateDomain,它确实解决了我的问题,但它也需要我为已经加载的 API 对象提供一个编组策略。换句话说,如果您正在针对具有类似于以下 API 的插件框架进行编程:

public void DoMyPluginsFunctionality(ApiProvidedInputContext context){

  var myPlugin = AppDomain.Create(
      strongName: "MyCompany.MyPlugin.; Version=1.2.3.4 ...",
      baseDirectory: "C:\\Program Files\\MyPlugin\\bin"
  )
  //success! MyCompany.MyPlugin loads the version of GRPC I want!

  myPlugin.unWrapAsDynamicProxy().doFunctionality(context)
  //error: No marshalling strategy and/or not serializable and/or swizzling errors
}

然后运行时将要求您编组(序列化)context变量,因为 .net 不允许您跨 AppDomain 边界共享内存。

所以我的新问题: - 鉴于我自己不能使用 AppDomains - 鉴于 Grpc.core 始终发布为AssemblyVersion=1.0.0.0

我有哪些选择?


更新2:

GRPC 构建系统看起来很大并且维护得很好,所以我希望我可以简单地构建它并更改 vcproj 文件以包含更新的版本字符串。

不幸的是,它看起来也很复杂,而且我还没有完全确定目标/交叉编译(x64 目标 x86)。

标签: c#.netvisual-studiolinkernuget

解决方案


推荐阅读