在过去的几周里,我一直试图破解这个,但还没有找到一个好的解决方案;希望我能在这里得到答案。
我有两个程序集(ZA和ZB),它们都指向一个公共项目/ dll(ZC),但它们可以是不同的版本(即相同的dll名称,相同的名称空间,某些类可能不同) 。但是,如果一个程序集在运行时由另一个程序集加载(例如A加载B),那么每个程序集都可以自行工作,那么我就无法使它工作。需要一些帮助。
以下是设置:
ZA需要在运行时加载需要在ZB中加载某些内容(这取决于ZC)。
ZA是主应用程序。
在bin
目录下,有一个插件目录plugins/plugin-ZB
,我希望在其下放置所有ZB及其依赖项(ZC)。
这是我到目前为止所尝试的内容:
Assembly.Load()
使用相同版本的dll - 工作正常。
Assembly.Load()
使用不同版本的dll - ZB加载,但是当方法运行时,我得到一个找不到异常的方法。
AppDomain.Load()
找不到文件错误;我甚至使用委托来解决集合。
有关ZC的一些细节:
- 一些方法是公共静态(有些不是)。例如。 Log.Log("hello");
- 有些人可能会返回值(基元或对象)。
- 某些方法是非静态的(和返回值)。
帮助? - TIA
答案 0 :(得分: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")
从现在开始,我使用后期绑定和/或反射来运行我的测试。
答案 1 :(得分:1)
除了Jonathan Allen的优秀建议外,解决问题的更“经典”方法是在2个不同的AppDomanis中加载2个版本。然后,您可以使用.NET Remoting使两个AppDomains通信。所以ZA应该在这个AppDomain ZB中创建一个新的Appdomain,Load并通过Remoting在ZB中调用一些操作。
请注意,.NET Remoting对您要使用的类有一些要求(从MarshalByRef继承),而创建AppDomain是一项昂贵的操作。
希望这个帮助
答案 2 :(得分:0)
我同时加载了同一个程序集的两个版本。它就像你描述的那样发生了。
您必须说服运行时为ZA和ZB加载相同版本的ZC。我找到了两种方法:
bindingRedirect
元素。 this question中有一些详细信息。AppDomain.AssemblyResolve
事件。 this answer中有一些详细信息。 AppDomain.AssemblyResolve
的唯一问题是它只在运行时找不到请求的版本时触发。如果两个版本都可用,那么您必须使用bindingRedirect
。我使用了AppDomain.AssemblyResolve
事件,然后添加了一个安全检查,通过查看程序集的引用程序集集来确保加载了正确的版本。如果不是,我向用户抱怨该库的旧版本就在它周围并告诉它们它在哪里。