When the .NET runtime needs to create an object it first needs to load the assembly the type is stored in. The basics of that process is not all that complex to understand and is a must know for every .NET developer. If the type is stored in the same assembly everything is nice and cozy as no searching for assemblies has to be done. Now the process gets interesting when the runtime has to go and search for another assembly.
One thing that makes quite a bit of difference is whether the assembly in question has a strong name and is deployed in the GAC. To use side by side deployment an assembly needs to be deployed to the GAC and for that a string name is required.
The first step for the runtime is to check if the assembly has been redirected using the app.config <bindingRedirect> and or <codeBase> elements. Of course the <bindingRedirect> element can only be used of the assembly has a strong name. If not the version is pretty much ignored. Note that beside the app.config the same checks are done in the assemblies publishers config file, unless explicitly disabled, and the machine.config.
Now we know the exact name, including version of the assembly to load. Next the runtime goes through the list of already loaded assemblies to check is the assembly is already loaded. Keep in mind that the version number is only used for assemblies with a strong name, is not only he actual assembly name is used.
So is the assembly wasn’t loaded and it contains a strong name the GAC is checked. Note that this takes precedence over the local directory. So the local copy of the assembly will be ignored if there is a version with the identical version number in the GAC.
If no suitable assembly was found in the GAC the runtime starts looking in other places. It uses the <codeBase> information found in the config files. If this is specified the runtime loads the file indicated. If not the runtime starts probing a number of directories. The first directory tried is the application installation directory. Next a subdirectory with the assembly name is tried, after that the culture and a combination of culture and assembly name. If still not found the runtime tries the binpath, first by itself and then combined with the culture and assembly name.
So that is quite a list of places the .NET runtime checks for a specific assembly, no wonder loading new assemblies can be somewhat slow.
Now the most important thing to remember is that only the GAC allows for side by side installation of multiple versions if an assembly and in order to do so it needs to be strongly named. Giving an assembly as strong name is simple, just open the projects properties, go to the Signing tab and check the Sign the assembly checkbox. Next specify the strong name key file, either by creating a new one or choosing an existing file. Next build the project to create the assembly.
Deploying the assembly to the GAC is done using GACUtil, a command line utility found in the .NET framework SDK. Use GACUTIL –i <assembly file> to install the assembly into the GAC. To check which versions are currently in the GAC you can use GACUTIL –l <assemblu name>.