tags:

views:

350

answers:

4

Dear all, 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

A: 

As far as I know you can't load another version of an already loaded assembly in the same application domain.

Otávio Décio
+1  A: 

You can only have one version of an assembly for an AppDomain. If you want to load 2 version of the same assembly you must do this in different AppDomains. 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

Gian Marco Gherardi
A: 

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.

Don Kirkby
This isn't loading two different versions, it's loading the same version twice.
Cameron MacFarland
When I had this problem, @Cameron, the run time loaded version 1.1 of ZC when ZA started. Then when I loaded the ZB plug in, the run time loaded version 1.0 of ZC with it. That's what I mean by loading two different versions. To make ZA and ZB pass objects from ZC to each other, I had to make both of them load the same version of ZC. That's what I'm describing how to do in my answer. Have I misunderstood the original question?
Don Kirkby
A: 
    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.

http://stackoverflow.com/questions/2016990/net-load-two-version-of-the-same-dll/2023445#2023445

Jonathan Allen