LogoASPAlliance: Articles, reviews, and samples for .NET Developers
DLL Hell and Version Policy
by Anuj Sahu
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 45315/ 129


The heading of this article reflects that there are two topics and DLL hell is the problem and Version Policy is the solution to problem. Below is stated the problem with DLL hell is and how a developer can overcome this problem by defining his or her own Version policy.

DLL Hell - The Problem

DLL Hell refers to the set of problems caused when multiple applications attempt to share a common component like a Dynamic Link Library (DLL) or a Component Object Model (COM) class. One application will install a new version of the shared component that is not backward compatible with the version already on the machine. Although the application that has just been installed works fine, existing applications that depended on a previous version of the shared component might no longer work.

Example 1

We have an application APP1 of Version 1.0 and a plug-in to that application PLUG1 of version 1.0 which of course depends on shared DLL of APP1. But as we upgraded the APP1 to latest version 2.0, APP1 works fine, however, the plug-in PLUG1 is dependent on the shared DLL.

Version Policy-The Solution

Version policy is the user defined policies which the developer can include in his or her application which will redirect the other application looking for the DLL of the previous version of the application to the DLL of the latest version.

Example 2

Continuing the previous example, if the developer of APP1 would have included version policies in the latest version 2.0 then the application PLUG1 would have worked fine because when the application PLUG1 was looking for the shared DLLs of APP1 Version 1.0 it would have been redirected to the shared DLLs of APP1 version 2.0 by the version policy included in the version 2.0 of APP1 version 2.0.

Assemblies - The Building Blocks

Assemblies are the building blocks used by the .NET Framework to solve the versioning and deployment issues just described. Assemblies are the deployment unit for types and resources. In many ways an assembly equates to a DLL in today's world; in essence, assemblies are a "logical DLLs."

Versioning in .NET is done at the assembly level—nothing smaller, like a module or a type, is versioned. Also, assemblies are used to share code between applications

Please refer to MSDN for more details on Assemblies and Assemblies Manifest.


It is necessary to discuss here about private and shared assemblies because of the difference in naming convention of assemblies in case of private and shared assemblies.

Private Assemblies

An application-private assembly is an assembly that is only visible to one application. The naming requirements for private assemblies are simple: The assembly names must only be unique within the application. There is no need for a globally unique name. Keeping the names unique is not a problem because the application developer has complete control over which assemblies are isolated to the application.

This version information is not enforced for private assemblies because the developer has complete control over the assemblies that are deployed to the application directory.

Shared Assemblies

The .NET Framework also supports the concept of a shared assembly. A shared assembly is one that is used by multiple applications on the machine.

Shared assemblies can be placed in the Global Assembly Cache where CLR first searches for the assemblies. The global assembly cache is a machine-wide store for assemblies that are used by more than one application. Since it is shared by many other applications, developers do not have full control over it and special care is needed in case of shared assemblies.

For example, a shared assembly must have a name that is globally unique. Also, the system must provide for "protection of the name"—that is, preventing someone from reusing another's assembly name.

The .NET Framework allows applications and administrators to override the version of an assembly that is used by the application by specifying version policies.

Version Policy

Assembly manifest records information about the version of each dependency it was built against. However, as stated in the above example where the developer of APP2 may wish to run with a different version of a dependency at run time. The .NET Framework enables this flexibility in version binding through version policies.

Assembly Version Numbers

The parts of the version number are major, minor, build and revision. As a developer you are free to change any portion of this number as you see fit.

One typical convention is as follows.

Major or minor: Changes to the major or minor portion of the version number indicate an incompatible change. Under this convention then, version would be considered incompatible with version

Build: The Build number is typically used to distinguish between daily builds or smaller compatible releases.

Revision: Changes to the revision number are typically reserved for an incremental build needed to fix a particular bug. You will sometimes hear this referred to as the "emergency bug fix" number in that the revision is what is often changed when a fix to a specific bug is shipped to a customer.

Default Version Policy

The CLR determines which version of the dependency to load when it comes across a reference to that assembly in code. The default version policy in .NET is simple, the caller gets the exact version with which the application was built and tested against.

Custom Version Policy

This is the section we have been talking so long where the author does not want the CLR to load the default version and redirects the CLR to the other version defined by the Author.

Version policies are stated in XML files and are simply a request to load one version of an assembly instead of another.

Example 3

The following version policy directs the CLR to load version instead of version of an assembly called app1.engine.

Listing 1

            name=" app1.engine" 
            publicKeyToken="ebf6b2ff4d0a08aa" />
         <bindingRedirect oldVersion=""

This is just a simple XML file. The name of this file is policy.1.0.app1.engine.config. Just place the file exactly where app1.engine.dll exists, in case of shared assembly it may be GAC.

Example 4

You can also redirect from a range of versions to another version. For example, the following policy redirects all versions from through of app1.engine to version

Listing 2

            name=" app1.engine" 
            publicKeyToken="ebf6b2ff4d0a08aa" />
         <bindingRedirect oldVersion=""

This file is also similar to above example.

Different level of version policy

There are three levels at which version policy can be applied in .NET: application-specific policy, publisher policy and machine-wide policy.

Application-specific Policy

Each application has an optional configuration file that can specify the application’s desire to bind to a different version of a dependent assembly. The name of the configuration file varies based on the application type. For executable files, the name of the configuration file is the name of the executable + a ".config" extension. For example, the configuration file for "app1.exe" would be "app1.exe.config." Configuration files for ASP.NET applications are always "web.config."

Example 5

An application APP1 was developed with .NET Framework 1.1 and now we want to direct the application to start with .NET Framework 2.0. This means then, a XML file with the following codes and name of that file must be app1.exe.config must be placed in the exact directory where app1.exe is present and now APP1 will be redirected to .Net 2.0 when the application starts.

Listing 3

       <supportedRuntime version="v2.0.50727"/>
       <supportedRuntime version="v1.1.4322"/>

Publisher Policy

While application-specific policy is set either by the application developer or administrator, publisher policy is set by the vendor of the shared assembly. We have already discussed this.

Machine-wide Policy

The final policy level is machine-wide policy (sometimes referred to as Administrator policy). Policy statements made in machine.config affect all applications running on the machine. Machine-wide policy is used by Administrators to force all applications on a given machine to use a particular version of an assembly.

Policy Evaluation

The first thing the CLR does when binding to a shared named assembly is to determine which version of the assembly to bind to. The process starts by reading the version number of the desired assembly that was recorded in the manifest of the assembly making the reference. Policy is then evaluated to determine if any of the policy levels contain a redirection to a different version. The policy levels are evaluated in order starting with application policy, followed by publisher and finally administrator.


Hope this article makes you to understand what DLL hell is and how you can avoid your application falling into the condition of DLL hell by creating your own custom version Policies.









Product Spotlight
Product Spotlight 

©Copyright 1998-2021  |  Page Processed at 2021-12-05 6:49:31 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search