Many a time you might face this issue. Especially when you are using a third party component, which uses an older version of an assembly, of which you are using a newer version. Pre 2.0 (and I do not know for sure of 2.0) compiler compliant to the CLS do not support the functionality of a static reference of two differently versioned assemblies with the same name at compile time.
The safest way to do this is Load the assembly object at runtime using Assembly.Load and then calling the appropriate methods. Do not forget to give different display names to these. If the assemblies have strong names and they are Loaded then, they are treated as different assemblies by the CLR. If the assemblies are not strong names, even two identical assemblies loaded from different paths are considered two different assemblies. In both the cases (strongly named or not) even the identical types in the two assemblies are not castable to each other.  In other words, you have an Assembly X v1.0 with type A and type B. Type B changed with X v2.0 but type A did not. Even so, if you create an object of type A using the reference of Assembly X v1.0, you will not be able to cast it to the identical Type A of the Assembly X v 2.0. So do not design your application in such a way that you need to cast types in two different assemblies. Or otherwise, include a casting provider.
Code
Lets say we have an assembly AssemblyX. Version 1.0.0.0 has the following classes
public class A Â Â Â Â Â Â Â Â Â Â Â Â { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â public void WriteToConsole() Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Console.WriteLine(" Class A, AssemblyX version 1.0 " ); Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â Â Â Â Â }
public class B
{
public void WriteToConsole()
{
Console.WriteLine(" Class B, AssemblyX version 1.0 " );
}
}
        Version 2.0.0.0 of AssemblyX has the following classes
public class A
{
public void WriteToConsole()
{
Console.WriteLine(" Class A, AssemblyX version 2.0 " );
}
}
Â
public class B
{
public void WriteToConsoleV2()
{
Console.WriteLine(" Class B, AssemblyX version 2.0 " );
}
}
 AssemblyX v1.0.0.0 is already added as a static reference to our project, lets call it AssemblyLoader (console application), directly or indirectly. Following is the code I have used to load the newer version too, along with the older one, in the same AppDomain,
public class Loader
{
static void Main()
{
Loader _loader = new Loader();
_loader.LoadAndRunMethodsV1();
_loader.LoadAndRunMethodsV2();
_loader.TryCastA();
Console.ReadLine();
}
public void LoadAndRunMethodsV1()
{
AssemblyX.A _a = new A();
AssemblyX.B _b = new B();
_a.WriteToConsole();
_b.WriteToConsole();
}
public void LoadAndRunMethodsV2()
{
Assembly _assembly = Assembly.LoadFrom(@"E:\Blog\Assemblies\v2\AssemblyX.dll");
Type Av2 = _assembly.GetType("AssemblyX.A");
Type Bv2 = _assembly.GetType("AssemblyX.B");
object _a = Activator.CreateInstance(Av2);
object _b = Activator.CreateInstance(Bv2);
MethodInfo _mA = Av2.GetMethod("WriteToConsole");
MethodInfo _mB = Bv2.GetMethod("WriteToConsoleV2");
_mA.Invoke(_a,null);
_mB.Invoke(_b,null);
}
public void TryCastA()
{
try
{
Assembly _assembly = Assembly.LoadFrom(@"E:\Blog\Assemblies\v2\AssemblyX.dll");
Type Av2 = _assembly.GetType("AssemblyX.A");
object _a = Activator.CreateInstance(Av2);
Console.WriteLine(typeof(AssemblyX.A).AssemblyQualifiedName);
Console.WriteLine(Av2.AssemblyQualifiedName);
(_a as AssemblyX.A).WriteToConsole();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
When you run the console application, you get the following output. Notice the object reference exception you would get, because of the invalid cast between the the two classes.
Â
You would get the same results if you used strongly named assemblies.