c# - 从插件加载具有相同 AssemblyVersion 的多个.net 程序集
问题描述
我在dll地狱。
我正在为一个名为 ANSYS 的庞大、古老且非常强大的软件套件构建一个插件。他们有一个插件框架。我曾希望他们能通过AssemblyContext
s 或AppDomain
s 或其他一些我不理解的聪明的 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 引用包含在其中,并选择了“构建操作:请勿复制”。
所以我的问题:
我可以在运行时做一些简单易行的事情来告诉运行时链接器“当有人从你认为应该是的程序集中加载类型时grpc.core
,不要加载 1.0.0.0,准确地找到 1.16.0.0”?运行时已经通过“强名称”匹配所需的库。问题是 1.16.0 用词不当。该版本字符串是信息性的,但程序集本身是版本 1.0.0.0。Fusion 已经通过完全匹配加载了我想要的库。
- 我可以用 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
我有哪些选择?
- 停止使用 GRPC.core 的新功能并担心我的父进程依赖项
- 使用类似于 shading 的策略。.net 世界中有类似阴影的东西吗?
- 编辑已发布二进制文件的版本元数据。我可以动态编辑已发布的二进制文件版本吗?
- 使用更新的版本字符串自己重建 GRPC——实际上是 GRPC 的私有分支。
更新2:
GRPC 构建系统看起来很大并且维护得很好,所以我希望我可以简单地构建它并更改 vcproj 文件以包含更新的版本字符串。
不幸的是,它看起来也很复杂,而且我还没有完全确定目标/交叉编译(x64 目标 x86)。
解决方案
推荐阅读
- wxpython - 如何使 wx.Frame 闪烁
- c - 为什么我不能通过系统调用退出 shellcode?
- haskell - 无法将预期类型“IO [String]”与实际类型“[String]”匹配
- javascript - 如何解决这个问题 期望一个赋值或函数调用,而是看到一个表达式 no-unused-expressions
- javascript - Html:工具提示隐藏在带有滚动的分屏上的div上(需要在父容器上保留“overflow-y:auto”)
- c# - 来自 Javascript AJAX 的 ASP.NET MVC 操作调用收到 500 内部服务器错误
- javascript - Sorting order of randomly generated numbers with Javascript
- tensorflow - Tokenizer and Nietzsche
- c# - 没有为 Serilog SQL 服务器接收器日志记录错误
- jquery - Periodically call a method from controller and display updated returned data without reload