Loading 2 versions of assembly at runtime

给你一囗甜甜゛ 提交于 2019-11-30 05:24:43

问题


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


回答1:


    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")

From here on out I used late binding and/or reflection to run my tests.

.NET: Load two version of the same DLL




回答2:


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




回答3:


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:

  1. Use a bindingRedirect element in your App.config file. There are some details in this question.
  2. Use the 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 the bindingRedirect. I have used the AppDomain.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.



来源:https://stackoverflow.com/questions/1189372/loading-2-versions-of-assembly-at-runtime

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!