4

I have different versions of dlls for my .NET application and most of the time I want to use the latest one. However, there is one method which I run on a separate thread where I need to be able to select an older version of the dll based on some criteria.

I have learned that it is not possible to just load an assembly and then unload it within the default application domain (I can't just keep both versions loaded because then I'm running into duplicate definitions of types problem)

Probably I have to create a separate AppDomain, load the assembly there and then unload it. This application domain would execute just one method on a separate thread and would work with a different version of the library.

Do you think it is a good approach / have you better ideas / can you point me to some source which would get me started ?

Thanks a lot ;)

starblue
  • 55,348
  • 14
  • 97
  • 151
Tomas Vana
  • 18,317
  • 9
  • 53
  • 64

3 Answers3

9

Try something like this:

class Program
{
    static void Main(string[] args)
    {
        System.Type activator = typeof(ApplicationProxy);
        AppDomain domain = 
            AppDomain.CreateDomain(
                "friendly name", null,
                new AppDomainSetup()
                {
                    ApplicationName = "application name"
                });

        ApplicationProxy proxy = 
            domain.CreateInstanceAndUnwrap(
                Assembly.GetAssembly(activator).FullName,
                activator.ToString()) as ApplicationProxy;

        proxy.DoSomething();

        AppDomain.Unload(domain);
    }
}

And create a proxy class (must inherit from MarshalByRefObject)

class ApplicationProxy : MarshalByRefObject
{
    public void DoSomething()
    {
        Assembly oldVersion = Assembly.Load(new AssemblyName()
        {
            CodeBase = @"c:\yourfullpath\AssemblyFile.dll"
        });

        Type yourOldClass = oldVersion.GetType("namespace.class");
        // this is an example: your need to correctly define parameters below
        yourOldClass.InvokeMember("OldMethod", 
                                   BindingFlags.Public, null, null, null);
    }
}
RabtFt
  • 153
  • 15
Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
  • Thank you for the example, it has worked for me and solved my problem from http://stackoverflow.com/questions/2094487/how-can-i-use-workflows-with-older-versions-of-activity-libraries-in-rehosted-w/2108268#2108268 – Tomas Vana Jan 21 '10 at 10:08
  • Typo? "ApplicationProxy" should be "RemoteProxy", or vice-versa? – RenniePet Aug 06 '12 at 23:36
0

Why not rewrite you new library to have the older verion of the code in a different method and call when needed?

public void MyNewMethod(){}

public void MyLegacyMethod(){}
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • Actually I don't have too much control over this. My method generates workflow images based on activities from library and it needs to have the correct version of the library loaded to be able to work.. – Tomas Vana Jan 20 '10 at 09:44
0

Purhaps you could use extern alias, see what-use-is-the-aliases-property-of-assembly-references-in-visual-studio-8

You ought to be able to specify an alias for the two versions of the assembly, and use same prefix's in your code.

Community
  • 1
  • 1
Henrik Gering
  • 1,769
  • 16
  • 29