从插件加载具有相同AssemblyVersion的多个.net程序集

时间:2019-05-11 01:12:23

标签: c# .net visual-studio linker nuget

我在dll地狱中。

我正在为名为ANSYS的庞大,古老且功能强大的软件套件构建插件。他们有一个插件框架。我曾希望他们能够通过AssemblyContextAppDomain或我不理解的其他一些巧妙的dotnet设备为我神奇地处理一切。他们没有。

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

当我在还依赖于grpc 1.0.0.0的ANSYS进程空间中运行插件时,链接器会找到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。我将此记录为a request against GRPC。下面有更多内容。

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

所以我的问题:

  1. 有什么简单易行的操作可以告诉运行时链接程序“当有人从您认为应该为grpc.core的程序集中加载类型时,不要加载1.0.0.0,找到到底是1.16.0.0”?
      

    运行时已经通过“ strong”匹配了所需的库   名称”。问题在于1.16.0的使用不当。该版本   字符串仅供参考,但程序集本身是版本   1.0.0.0。 Fusion已经通过完全匹配加载了我想要的库。

  2. 我可以使用appdomain或上下文或其他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的更新功能,并担心我的父进程的依赖性
  • 使用a strategy similar to shading .net世界中是否存在阴影
  • 编辑已发布的二进制文件的版本元数据。 我可以动态编辑已发布的二进制版本吗?
  • 使用更新的版本字符串自己重建GRPC-有效地是GRPC的私有分支。

更新2:

GRPC构建系统似乎非常庞大且维护良好,因此我希望可以简单地构建它并更改vcproj文件以包含更新的版本字符串。

不幸的是,这似乎也很复杂,而且我还没有确定目标/交叉编译(x64目标是x86)。

0 个答案:

没有答案