在运行时加载2个程序集版本

6

我已经试图在过去的几周里解决这个问题,但还没有找到一个好的解决方案;希望我可以在这里得到答案。

我有两个程序集(ZA和ZB),它们都指向一个共同的项目/ dll(ZC),但可能是不同版本的(即相同的dll名称,相同的命名空间,某些类可能不同)。每个程序集单独工作,但如果其中一个在运行时被另一个加载(例如A加载B),那么我就无法使其工作。需要一些帮助。

这是设置:

  • ZA依赖于ZC(公共)版本1.1
  • ZB依赖于ZC版本1.0

ZA需要在运行时加载ZB中的内容(它依赖于ZC)。

ZA是主应用程序。 在其bin目录下,有一个插件目录plugins/plugin-ZB,我想在其中放置所有ZB及其依赖项(ZC)。

到目前为止,我尝试过以下方法:

Assembly.Load()使用相同版本的dll-工作正常。

Assembly.Load()使用不同版本的dll- ZB会加载,但当方法运行时,我会收到一个方法未找到的异常。

AppDomain.Load()出现文件未找到错误;我甚至使用了委托来解决程序集。

有关ZC的一些详细信息: - 一些方法是公共静态的(有些不是)。例如Log.Log("hello"); - 一些可能返回值(原始或对象)。 - 一些方法是非静态的(并返回值)。

需要帮助吗? - TIA

3个回答

3
    m_Assembly1 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "Old Version\Some.dll"))
    m_Assembly2 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "New Version\Some.dll"))

    Console.WriteLine("Old Version: " & m_Assembly1.GetName.Version.ToString)
    Console.WriteLine("New Version: " & m_Assembly2.GetName.Version.ToString)

    m_OldObject = m_Assembly1.CreateInstance("FullClassName")
    m_NewObject = m_Assembly2.CreateInstance("FullClassName")

从这里开始,我使用了晚期绑定和/或反射来运行我的测试。

.NET:加载两个版本的相同DLL


非常好的建议!我不知道那个。 - Gian Marco

1
除了Jonathan Allen的优秀建议外,解决问题的更“传统”方法是在两个不同的AppDomain中加载2个版本。然后,您可以使用.NET Remoting来使这两个AppDomains通信。因此,ZA应该创建一个新的AppDomain,在此AppDomain中加载ZB,并通过Remoting调用ZB中的某些操作。
请注意,.NET Remoting对您想要使用的类(从MarshalByRef继承)有一些要求,并且创建AppDomain是一项昂贵的操作。
希望这可以帮助到您。

“一个AppDomain只能有一个程序集版本”这句话并不正确。实际上,甚至可以从单个程序集引用两个版本的程序集。查找extern alias以获取更多信息,以下是谷歌搜索中出现的第一篇文章,其中包含该功能的示例:http://blogs.msdn.com/b/ansonh/archive/2006/09/28/extern-alias-walkthrough.aspx - Graham
使用两个AppDomains是解决所描述的问题的一种方法。 - Graham

0

我曾经同时加载了同一程序集的两个版本。这种情况就像你描述的那样发生了。

你必须说服运行时为ZA和ZB都加载相同版本的ZC。我已经找到了两种方法:

  1. 在你的App.config文件中使用bindingRedirect元素。有关详细信息,请参见this question
  2. 使用AppDomain.AssemblyResolve事件。有关详细信息,请参见this answer

AppDomain.AssemblyResolve 的唯一问题是它只在运行时找不到所请求的版本时触发。如果两个版本都可用,则必须使用 bindingRedirect。我已经使用了 AppDomain.AssemblyResolve 事件,然后添加了一个安全检查,通过查看程序集的引用程序集集合来确保加载了正确的版本。如果没有加载正确的版本,我会向用户抱怨库的旧版本仍然存在,并告诉他们它在哪里。


1
这不是加载两个不同版本,而是加载了两次相同的版本。 - Cameron MacFarland
1
当我遇到这个问题时,@Cameron,运行时加载了ZC的1.1版本,当ZA开始运行时。然后当我加载ZB插件时,运行时同时加载了ZC的1.0版本。这就是我所说的加载两个不同版本的意思。为了使ZA和ZB能够相互传递ZC对象,我必须让它们都加载ZC的相同版本。这就是我在我的回答中描述如何做到这一点的方法。我是否误解了原始问题? - Don Kirkby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接