views:

203

answers:

3

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

A: 

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
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..
Thomas Wanner
+3  A: 

Try something like this:

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

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

        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);
    }
}
Rubens Farias
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
Thomas Wanner
A: 

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.

Henrik Jepsen