DLL Hell. Enough said, well maybe not. Before .NET every installation of a new version of a program or the installation of any program was a gamble. There was always a risk that a necessary component required to run the new version would overwrite a component which is used by another causing the old program to stop working.
We generally got around this by having very tight controls over what was installed on a system and/or significant testing cycles before making the installation on a live environment.
Even with the introduction of COM, we still had to manage, control and monitor the registry entries before and after an release cycle.
Then along comes .NET and removes one of the most demanding and nerve wracking technical problems ever with the introduction of Assemblies. An assembly is liken to a DLL, however it contains much more information and detail than an unmanaged DLL does. The additional information is, for example, the Metadata which is accessible through the Reflection libraries and provides the data types of properties, a list of other assemblies which call the current assembly, permission rights, version and a definition of the assembly itself.
There are generally 2 types of assemblies. The first is a private assembly. This assembly (DLL) is installed within the same directory or sub-directory with the other components that use it. No other program outside of that directory can access or use the DLL.
The second type of assembly is referred to as a shared assembly and is installed into the Global Assembly Cache (GAC). A shared assembly means that the DLL can be used by more than 1 program. Because of this the CLR needs to know where to find it. If the CLR does not find it in the working directory or a sub-directory, then it looks into the GAC. You can use the gacutil to install a DLL into the GAC by using the following command line:
You can view or modify the assemblies installed in the GAC within Windows Explorer. Find the assembly directory within the Windows directory.
Take note of a security hazard when using shared assemblies. It would be possible for someone other than the original publisher to release an assembly with the same name. If this happens and both are installed into the GAC on the same computer then there is potential for the program to use the wrong DLL. The solution to this is to implement a strong name using the Sn command (available within the SDK tool), where the programmer creates a key pair, signs the assembly using the private key and provides the public key to programs calling the assembly.
The next feature which prevents DLL Hell and improves deployment is the concept of Versioning. When you right-click a DLL and select properties, you will generally get a window which has a tab named Version. The version of the component/assembly/DLL usually resembles 18.104.22.168. By having an associated version of the assembly a programmer can decide which version of an assembly to use or if a known version is incompatible, code can be written to make sure that version is not used. The CLR uses the version to determine which dependency to use, by default the version numbers should match exactly. However, it is possible, as already mentioned, to use a different dependent assembly which is configurable via the programs configuration file with a scope of program, publisher policy or machine wide.