【问题标题】:(.NET) How do I deal with two versions of the same type when I'm building a plugin?(.NET) 在构建插件时如何处理相同类型的两个版本?
【发布时间】:2009-05-28 20:19:34
【问题描述】:

我们正在为使用最新版本的商业 UI 框架的商业应用程序构建一个插件。我们的插件引用了同一框架的不同(旧)版本以及它插入的应用程序的 API dll。我们现在在加载商业应用程序的某些部分时在运行时遇到重复类型冲突 (CS0433)。

这是(或多或少)这种情况:

http://img39.imageshack.us/img39/769/conflictingreferences.jpg

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: .net plugins


    【解决方案1】:

    通用 UI 从何而来,升级难度如何?

    在我看来这是最好的方法。

    【讨论】:

    • 大约有 50 万行“困难”代码(技术上并不困难,只是大泥球),以及一个在任何给定时间有 10 件其他事情的小团队,以及无限堆叠的直接支持工作。我们和其他应用程序正在使用的版本之间有 5 个框架版本。另外,如果没有必要,我真的不想将我们绑定到该框架的其他应用程序版本。
    • 啊-您是否调查过链接到特定版本的框架?不确定根据您的设置是否有可能。
    • 不幸的是,问题不在于我们的代码 - 应用程序正在尝试加载其框架副本并遇到类型冲突。
    • 我们最终采用了这种策略。我正在考虑通过网桥将整个插件加载到单独的 AppDomain 中,但我们认为这将显着增加工作量,并且将来更容易损坏。我不喜欢它,但我想宇宙并没有特别担心我在这种情况下喜欢什么。
    【解决方案2】:

    我认为 .NET Framework(至少到 3.5)实际上不能将单个程序集的两个不同版本加载到应用程序中。我相信我在某处读到 4.0 可能在该领域有一些额外的功能,但我不一定会指望它。

    唯一可行的方法是加载插件的应用程序将它们加载到单独的 AppDomain 中,但我假设您无法控制加载应用程序。

    总而言之,我认为没有升级您用于实现插件的库版本,我认为您目前无法解决此问题。

    【讨论】:

    • 顺便说一句,对于我可以更好地控制加载方案的单独插件,我们使用 AppDomain 方法。设置起来并不简单,但我认为花一两天时间让事情正常运行是值得的。
    【解决方案3】:

    在应用程序配置文件中使用策略或重定向来告诉框架使用新版本来替代插件请求的旧版本。

    MSDN has some info on this.

    【讨论】:

    • 不过,我们不是在谈论一两个版本的差异。这里需要担心的是,新版本几乎可以肯定与我们当前使用的版本部分或全部不兼容,并且会破坏我们的 UI 代码(可能以难以检测的方式)。
    • 解决这个问题的一种方法是保留带有 [Obsolete] 标记的旧 API 调用(您可以使 Obsolete 属性在编译时抛出错误,这样就无法针对过时的代码编译新代码方法)。
    【解决方案4】:

    我在这里回答了这个问题Compile Error CS0433 on pre-compiled ASP.NET 2.0 site

    您可以在代码中使用 extern 和 alias 关键字,并在引用程序集时指定新的(默认全局除外)别名。

    extern alias global2;
    using global2::System;
    

    【讨论】:

    • 这适用于编译错误,但不适用于运行时错误。我已经尝试过使用别名,但它们并没有解决问题。
    【解决方案5】:

    是的,你正在寻找标题中的动态信息,因为它说的是“建筑”。

    你试过this app.config设置吗?

    <configuration> Element
      <runtime> Element
        <assemblyBinding> Element for <runtime>
          <qualifyAssembly> Element
    
    <qualifyAssembly partialName="PartialAssemblyName"
                                      fullName="FullAssemblyName"/>
    

    this 一个怎么样?

    <configuration>
       <runtime>
          <assemblyBinding>
             <dependentAssembly>
    <bindingRedirect  
       oldVersion="old assembly version"
       newVersion="new assembly version"/>
    

    假设您已经尝试过 Assembly::Load,它是 Assembly.LoadWithPartialName 的替代品,两者都应该允许您在不指定任何版本信息的情况下进行加载。

    您是否阅读过 Dave Grimes workshop for fusion? 它非常全面,深入探讨了如何管理 CLR 的类型解析系统。他还有一个很好的安全和 .net 检测研讨会可供启动。

    【讨论】:

    • 我忘了说,你可能需要更具体地了解这个架构才能真正回答比我们这些迄今为止更好的答案,你在哪个层操作真的很模棱两可,这留下了很多开放式的“是吗?”...
    猜你喜欢
    • 2014-08-16
    • 2012-01-22
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多