在运行时加载 2 个版本的程序集
在过去的几周里我一直在尝试破解这个问题,但还没有找到一个好的解决方案; 希望我能在这里得到答案。
我有两个程序集(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)。
这是我到目前为止所尝试过的:
使用相同版本的 dll Assembly.Load()
- 工作正常。
Assembly.Load()
使用不同版本的 dll - ZB 加载,但是当该方法运行时,我收到方法未找到异常。
AppDomain.Load()
出现文件未找到错误; 我什至使用委托来解析程序集。
关于ZC的一些细节: - 有些方法是公共静态的(有些不是)。 例如 Log.Log("hello");
- 有些可能返回值(原语或对象)。 - 一些方法是非静态的(并且返回值)。
帮助? - 短暂性脑缺血发作
I've been trying to crack this one over the last couple of weeks and have not found a good solution yet; hopefully I can get an answer here.
I have two assemblies (ZA & ZB), both of which point to a common project/dll (ZC) but which could be on a different version (i.e. same dll name, same namespaces, some classes may be different). Each assembly works by itself, however, if one is loaded by the other at runtime (e.g. A loads B), then I cannot get it to work. Need some help.
Here's the setup:
- ZA depends on ZC (common) version 1.1
- ZB depends on ZC version 1.0
ZA needs to load needs to load something in ZB (which depends on ZC), at runtime.
ZA is the master app.
Under its bin
directory, there's a plugins directory plugins/plugin-ZB
under which I would like to place all of ZB and its dependencies (ZC).
Here's what I've tried so far:
Assembly.Load()
using same version of dll - worked fine.
Assembly.Load()
using different versions of dll - ZB loads, but when the method runs, I get a method not found exception.
AppDomain.Load()
got a file not found error; I even used the delegate to resolve assemblies.
Some details regarding ZC:
- some methods are public static (some are not). E.g. Log.Log("hello");
- some may return values (primitives or objects).
- some methods are non static (and return values).
Help? - TIA
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从现在开始,我使用后期绑定和/或反射来运行我的测试。
.NET:加载同一 DLL 的两个版本
From here on out I used late binding and/or reflection to run my tests.
.NET: Load two version of the same DLL
除了 Jonathan Allen 的出色建议之外,解决问题的更“经典”方法是在 2 个不同的 AppDomanis 中加载 2 个版本。 然后,您可以使用 .NET Remoting 使两个 AppDomain 进行通信。 所以ZA应该创建一个新的Appdomain,在这个AppDomain中加载ZB并通过Remoting调用ZB中的一些操作。
请注意,.NET Remoting 对您要使用的类有一些要求(从 MarshalByRef 继承),并且创建 AppDomain 是一项昂贵的操作。
希望这有帮助
Apart from Jonathan Allen excellent advice, a more "classical" way to resolve the problem is by loading the 2 versions in 2 different AppDomanis. You can then use .NET Remoting to make the two AppDomains comunicate. So ZA should create a new Appdomain, Load in this AppDomain ZB and invoke some operation in ZB via Remoting.
Note that .NET Remoting has some requirements on the classes that you want to use (inheritance from MarshalByRef), and creating an AppDomain is an expensive operation.
Hope this help
我同时加载了同一程序集的两个版本。 正如您所描述的那样,它发生在一个场景中。
您必须说服运行时为 ZA 和 ZB 加载相同版本的 ZC。 我找到了两种方法来做到这一点:
bindingRedirect
元素。 此问题中有一些详细信息。AppDomain.AssemblyResolve
事件。 这个答案。AppDomain.AssemblyResolve
的唯一问题是它仅在运行时找不到请求的版本时才会触发。 如果两个版本都可用,那么您必须使用bindingRedirect
。 我使用了 AppDomain.AssemblyResolve 事件,然后添加了安全检查,以确保通过查看程序集引用的程序集集合来加载正确的版本。 如果不是,我会向用户抱怨该库的旧版本正在闲置,并告诉他们它在哪里。I have had two versions of the same assembly loaded at the same time. It happened with a scenario just as you describe it.
You have to convince the runtime to load the same version of ZC for both ZA and ZB. I have found two ways to do that:
bindingRedirect
element in your App.config file. There are some details in this question.AppDomain.AssemblyResolve
event. There are some details in this answer.The only problem with
AppDomain.AssemblyResolve
is that it only triggers when the runtime can't find the requested version. If both versions are available, then you'll have to use thebindingRedirect
. I have used theAppDomain.AssemblyResolve
event and then added a safety check that makes sure the right version was loaded by looking through the assembly's referenced assemblies collection. If it isn't, I complain to the user that an old version of the library is lying around and tell them where it is.