Niraj Bhatt – Architect's Blog

Ruminations on .NET, Architecture & Design

Loading 2 Versions of the same .NET Assembly

This can be an interview question 🙂 . Let’s say I have a class

public class Class1 //1.0.0.0 – in C:
{
public string SayHello()
{
return “Hello World”;
}
}

and I version it to 2.0.0.0

public class Class1 // in C:\2 folder
{
public string SayHello()
{
return “Hello India”;
}
}

So you have 2 assemblies. Now, write a program in .NET to print Hello World & Hello India. Simple – use Assembly.LoadFrom (LoadFrom takes a path while Load goes through Assembly Resolver & Loader).

class Program
{
static void Main(string[] args)
{
Assembly assm = Assembly.LoadFrom(@”C:\ClassLibrary1.dll”);
Type[] types = assm.GetTypes();
foreach (var t in types)
{
Object obj = assm.CreateInstance(t.FullName);
Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}

Assembly assm2 = Assembly.LoadFrom(@”C:\2\ClassLibrary1.dll”);
Type[] types2 = assm2.GetTypes();
foreach (var t in types2)
{
Object obj = assm2.CreateInstance(t.FullName);

Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}
}
}

But to your suprise the output remains – “Hello World” & “Hello World”. If you take the second block first, output will change to “Hello India” & “Hello India”. Neither of them is what we expected. Conclusion – It’s not possible to load 2 assemblies by same name inside a single AppDomain. So you will have to create a seperate AppDomain & load the second version of assembly into it as shown below:

class Program
{
static void Main(string[] args)
{
Assembly assm = Assembly.LoadFrom(@”C:\ClassLibrary1.dll”);
Type[] types = assm.GetTypes();
foreach (var t in types)
{
Object obj = assm.CreateInstance(t.FullName);
Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}
AppDomain app = AppDomain.CreateDomain(“Child”, AppDomain.CurrentDomain.Evidence, new AppDomainSetup { ApplicationBase = @”C:\2″ });
Assembly assm2 = app.Load(@”ClassLibrary1″);
Type[] types2 = assm2.GetTypes();
foreach (var t in types2)
{
Object obj = assm2.CreateInstance(t.FullName);

Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}
}
}

Do you have any better ways?

Advertisements

One response to “Loading 2 Versions of the same .NET Assembly

  1. N'ther architect September 8, 2009 at 8:25 pm

    Cross Domain Calls: In your case, Console.WriteLine(t.GetMethod(”S …. is a cross domain call. In most cases, that’s not acceptable. But it is a valid solution nonetheless.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: