In this blog post, I'll discuss some of the techniques that you can use for loading the assemblies in .NET and troubleshoot the loading process in case you get stuck. Basically, you will learn…
Without further ado, and scaring you with the mumbo jumbo of assemblyBinding, probing and other processes, let us get straight to action. We shall learn along the way.
Create a new Project using Visual Studio. You can use any name, but for the sake of this post, it would be better if you stick with the ones I use. So, the project name is AssemblyLoadExample, and it is created in C:\Sample

Open Program.cs file and replace the existing code with…
using System;
using MyClassLibrary;
namespace AssemblyLoadExample
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(MyClass.Foo());
}
}
}
Create a new class library project in a SEPARATE instance of Visual Studio with the following details… MyClassLibrary in folder C:\Sample

Go to Class1.cs file in the classlibrary, and delete every line of code. Replace it with…
using System.Reflection;
namespace MyClassLibrary
{
public class MyClass
{
public static string Foo()
{
return string.Format("Returning from MyClass Version = {0}",
Assembly.GetExecutingAssembly().GetName().ToString());
}
}
}
Open AssemblyInfo.cs file and change the AssemblyVersion from 1.0.0.0 to 1.0.0.1
[assembly: AssemblyVersion("1.0.0.1")]
Go to the project properties… and select Signing. Then click New…

Provide a Strong Name key, uncheck Protect my key…. check box and click OK.

Compile the class library now. Let's get on with the main project -> AssemblyLoadExample
DO NOT add a project reference. Instead, add a Reference and click Browse to locate the assembly. Locate the assembly, and click Add.

If you have done everything correctly so far you would have a console application that shows the following when executed.

The boring part is done. Now, some interesting bits.
Remove MyClassLibrary reference from the Project AssemblyLoadExample.
Rename "C:\Sample\MyClassLibrary\MyClassLibrary\bin\Debug\MyClassLibrary.dll" to "C:\Sample\MyClassLibrary\MyClassLibrary\bin\Debug\MyClassLibraryV1.dll"
Add the reference "C:\Sample\MyClassLibrary\MyClassLibrary\bin\Debug\MyClassLibraryV1.dll" to the project.
Does the project Compile? -> Yes.
Does the project Run? -> NO!!!
It would throw an error message…
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or ass
embly 'MyClassLibrary, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9fe6f24b
59015723' or one of its dependencies. The system cannot find the file specified.
at AssemblyLoadExample.Program.Main(String[] args)
Why? Notice the fact that while loading the assembly it is still referencing MyClassLibrary whereas, you have already changed the name of the file to MyClassLibraryV1
Open Fusion Log Viewer. Mine is located at…
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\FUSLOGVW.exe"
Click Settings and change the Custom log path. Also change ensure that Log all binds to disk is checked along with Enable Custom Log path.

Now, run the application AssemblyLoadExample directly from "C:\Sample\AssemblyLoadExample\AssemblyLoadExample\bin\Debug"
Switch to Fusion Log Viewer and refresh. You should be able to see some entries there…

Double click on the 2nd one which shows MyClassLibrary as Description… and it will open a browser that will show you how probing happened and why your application failed.
Our job is to now help the application in finding the correct name of the assembly.
Switch back to your AssemblyLoadExample and add an app.config file.

Modify your app.config file to look like the following…
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyClassLibrary" culture="neutral"
publicKeyToken="9fe6f24b59015723"/>
<codeBase version="1.0.0.1"
href="file:///C:/Sample/MyClassLibrary/MyClassLibrary/bin/Debug/MyClassLibraryV1.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Do remember to change the publicKeyToken. You can use sn -T <assemblyName.dll> or simply use the fusion
log output that you saw earlier.
Run the application now, and you should be successfully able to see the output.

Essentially, what you have just done is to use assemblyIdentity tag to figure out which assembly you want to set the redirection to. This redirection is set by <codeBase> tag as you can see above.
Let's assume that somebody want to upgrade the DLL now.
Copy the existing MyClassLibrary project and paste it as MyClassLibraryV2

Open the solution from C:\Sample\MyClassLibraryV2
Change the assembly version to 2.0.0.0 and change the code to…
using System.Reflection;
namespace MyClassLibrary
{
public class MyClass
{
public static string Foo()
{
return string.Format("Giving back from MyClass Version = {0}",
Assembly.GetExecutingAssembly().GetName().ToString());
}
}
}
Recompile the class library and close visual studio.
Switch back to AssemblyLoadExample and remove MyClassLibrary reference.
Rename "C:\Sample\MyClassLibraryV2\MyClassLibrary\bin\Debug\MyClassLibrary.dll" to "C:\Sample\MyClassLibraryV2\MyClassLibrary\bin\Debug\MyClassLibraryV2.dll"
Now change the App.config to the following and ensure everything works as expected…
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyClassLibrary" culture="neutral"
publicKeyToken="9fe6f24b59015723"/>
<codeBase version="2.0.0.0"
href="file:///C:/Sample/MyClassLibraryV2/MyClassLibrary/bin/Debug/MyClassLibraryV2.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
As you can see, you can change the version and codefile at the same time.
What if you want to use the different versions of the DLL in the same console?
Let's try to add both the references.

Will this compile? -> NO. Obviously, it is because of the conflict!
In this case, you are out of luck since Visual Studio doesn't provide enough support. Do remember that, you will have to rename the files back to the original file names, MyClassLibrary. Naturally, the locations will differ. Before you proceed further, deploy the assemblies into the GAC and use command line to compile your application.
First of all, change your code to look like the following…
extern alias oldMyClass;
extern alias newMyClass;
using System;
namespace AssemblyLoadExample
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(oldMyClass::MyClassLibrary.MyClass.Foo());
Console.WriteLine(newMyClass::MyClassLibrary.MyClass.Foo());
}
}
}
Then, go the Visual Studio command prompt and issue the following command…
csc.exe /out:"C:\Sample\AssemblyLoadExample\AssemblyLoadExample\bin\Debug\AssemblyLoadExample.exe" "C:\Sample\AssemblyLoadExample\AssemblyLoadExample\Program.cs"
/r:oldMyClass="C:\Sample\MyClassLibrary\MyClassLibrary\bin\Debug\MyClassLibrary.dll"
/r:newMyClass="C:\Sample\MyClassLibraryV2\MyClassLibrary\bin\Debug\MyClassLibrary.dll"
Also, now that everything is getting referenced directly from GAC, you will need to clear off your app.config.
Run your application now…
Returning from MyClass Version = MyClassLibrary, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9fe6f24b59015723
Giving back from MyClass Version = MyClassLibrary, Version=2.0.0.0, Culture=neutral, PublicKeyToken=9fe6f24b59015723
There you go… both the versions in the same application.
Some people will never learn anything because they understand everything too soon. - Alexander Pope