【问题标题】:Dynamically loading an assembly causing versioning errors动态加载程序集导致版本控制错误
【发布时间】:2013-01-10 19:32:21
【问题描述】:

我有一个可以动态运行多个插件的应用程序。安装应用程序后,用户只需将相应的插件放入安装目录,程序就会根据界面动态加载它们。

我遇到的问题是插件引用了主应用程序中的一个库来访问正确的界面并共享全局设置。我希望能够随时添加插件,而无需用户重新安装。但是,由于插件引用了一个库,当我尝试加载它们时,我收到了错误:

Could not load file or assembly 'program', Version=0.1.0.24838, Culture=neutral, PublicKeyToken=623917...' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

我知道如果我将所有插件添加到安装程序中可以避免此错误,但如果我稍后添加新插件,用​​户将不得不卸载并重新安装。动态加载插件的原因是用户只需放入一个新插件,它就可以工作了。

有没有办法让插件引用主应用程序中的对象而不用担心应用程序的版本?

谢谢。

【问题讨论】:

  • 这是非常经典的 DLL Hell,插件有一个依赖程序集,但 CLR 发现了一个版本号错误的程序集。您可能需要重新考虑“将程序集放在文件夹中”的方法。

标签: c# plugins dynamic-loading


【解决方案1】:

如果更改仅在插件程序集版本中,您可以将runtime binding redirect 用于更改的程序集。

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

您可以通过单独的补丁(zip 文件)提供更新。 (无需安装/卸载)。

【讨论】:

  • 我担心的是主应用程序可能是v.1.0,而插件a是1.1版本,插件b是1.2。另一个人可能正在运行应用程序的 v. 2,但使用相同的两个插件。我希望有一种方法可以使插件版本的动态加载独立。我在想一个接口可以工作,但插件仍然需要引用主程序集才能访问它。
  • 可以使用反射,不需要参考。这就是使用插件的要点。如果需要引用,则不会被命名为插件
【解决方案2】:

常见的方法是制作具有显式版本的特殊“公共接口”程序集(仅在接口更改时更改)并将插件和主应用程序链接到该程序集。您仍然需要为此类程序集提供向后兼容性并使用绑定重定向(即按照 Tilak 的 +1 答案中所示进行配置)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 2014-10-10
    相关资源
    最近更新 更多