The Answer to DLL Hell
The .NET platform’s answer to DLL Hell and to all of its problems is assemblies. Assemblies are self-describing installation units, consisting of one or more files. One assembly could be a single DLL or EXE that includes metadata, or it can be made of different files, for example, resource files, metadata, DLLs, and an EXE. Installation of an assembly can be as simple as copying all of its files. An xcopy installation can be done. Another big feature of assemblies is that they can be private or shared. With COM this differentiation doesn’t exist, because practically all COM components are shared. If you search for a COM component in the registry or use OLEView, you have to walk through hundreds and hundreds of components. Only a small number of these components were ever meant to be used from more than one application; however, every component must have a global unique identifier (GUID).
There’s a big difference between private and shared assemblies. Many developers will be happy with just private assemblies. No special management, registration, versioning, and so on is needed with private assemblies. The only application that could have version problems with private assemblies is your own application. The private components you use within your application are installed at the same time as the application itself. Local application directories are used for the assemblies of the components, so you shouldn’t have any versioning problems. No other application will ever overwrite your private assemblies. Of course, it is still a good idea to use version numbers for private assemblies too. This helps a lot with code changes, but it’s not a requirement of .NET.
With private assemblies you can still have versioning problems during development time. For example, if a component you use in your application references version 1 of assembly X, and you use version 2 of assembly X in your application, which version of the assembly is copied to your application directory?
The answer depends on what assembly you have referenced first - this versioning problem must be solved during development time. On the installed system, a hot fix can be easily applied to an application by simply replacing a private assembly with a new version. The only application that could have problems with the new version is the one where this fix is applied, because no other applications can be influenced.
When using shared assemblies, several applications can use this assembly and have a dependency on it. With shared assemblies, many rules must be fulfilled - a shared assembly must have a special version number, a unique name, and usually it’s installed in the global assembly cache.