If you have multiple controls in your ASP.Net, especially third-party ones, which in turn have a dependency on another third-party component, you are in for a world of pain if different controls use different versions of the same third-party component. Since your app has only one "bin" folder where all the assemblies reside, putting one version of the third-party component will break controls that rely on the other version. Luckily, the .Net developers devised some good solutions. Although I would not call this an elegant solution to DLL hell, at least its possible to have a solution that works.
Here are some sample web application scenarios and solutions involving assembly version conflicts, different assembly versions and location of assemblies. This is a small portion of a much larger .Net design involving the GAC etc., but I am not going to delve into that.
1) Placing assemblies outside the bin folder.
Sometimes you have an app with many assemblies and you want to keep them more organized. .Net allows this by providing a way to specify the folders where it should search. Modify your web.config as below:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;somefolder\bin" />
</assemblyBinding>
</runtime>
</configuration
You can specify as many folders as necessary in a semi-colon separated list which fusion will use to locate an assembly.
2) Having multiple versions of the same assembly in the same app space.
In this example, two versions of the ThirdParty assembly are placed in numbered sub-folders of bin. Both can co-exist and will work correctly.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="ThirdParty" publicKeyToken="16dcc87a28w7w7b1" />
<codeBase version="1.4.0.0" href="bin\14\ThirdParty.dll" />
<codeBase version="1.2.0.0" href="bin\12\ThirdParty.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
3) Redirecting an assembly from an older to a newer version.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly" publicKeyToken="32ab4ba45e0a69a1" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
You can only use #2 or #3 with strong named assemblies.