Friday, December 19, 2008

DLL Hell... Who Says it's History?

I must admit to being in a really anti-Microsoft mood today. I don't necessarily agree with that Mac guy on TV, but I still have reason to be down on Ballmer and company. I started my day by trying to install SQL Server 2008 and associated tools. This led to dozens of other required installations, reboots, and installer sessions that just hang. 2 of them, in fact. This operating system has too many moving parts if really technical people end up in this kind of trouble. I'm still not finished, and it's an open question regarding how many days I will spend on this.

Enough venting; on to the main topic. The introduction of the .Net Framework was hailed with proclamations of "the end of DLL hell". OK... I'd been writing DLLs for years, and I simply never had problems. Like alot of developers, my team has established practices in place that allow us to avoid DLL version conflicts.

Out came .Net 10 years ago, and I tried my first project. I compiled, and the assembly version automatically increments. Neat! I had to write plug-ins to do that in the past. So I wrote a windows forms application that used a couple of .Net DLLs by yours truly. I found a bug in a DLL, went to recompile it, and BAM! The exe was now broken. Hmm...

As I understand DLLs, they were always supposed to be upward compatible. You never change or remove an export; you only add them or change underlying code. You can fix a large, multi-component piece of software by simply upgrading a single DLL file. Now with .Net, you have to recompile ALL dependent components in order to distribute the tiny little fix. This is called coupling, and it's supposed to be a thing to avoid in object oriented development.

Yes, there are ways to allow flexible version compatibility. In other words, application A.exe can use versions 1 to 1.9.* of B.dll. Is it easy? Hell no! For our particular use case, we had to create something called "policy assemblies". How intuitive! My team uses policy assemblies for one of our products, and it took a great deal of time to put build processes in place. See http://support.microsoft.com/kb/891030.

This is all in the name of "Side by Side Installations" (SxS). You can have 2 different versions of the same DLL installed in your GAC, and the dependent component will select the right one to load. Big whoop. We've always had side by side installations of components. It's called folders, and we've always been able to use them to store different versions of the same file. There are oodles of ways to force one component to reference a specific version of another by loading it from a specific place. There's LoadLibrary. There's delay loading, which you can customize the behavior of (http://msdn.microsoft.com/en-us/library/aa733960(VS.60).aspx, search on PDelayLoadInfo and hook). Finally, there's a well-known search path protocol for loading modules.

But I hearken back to, why do we even need SxS versions of the same component? The lifecycle of a component in my world is such that we release, we maintain/fix it, and we increment the version number. It's generally upwardly compatible (with some rare exceptions requiring companion components to be updated at the same time). If there's a breaking change, we give the DLL a new name and start the lifecycle over.

In the 2005 and 2008 versions of MSVC, when I want to create a good old fashioned Win32 DLL, the compiler wants to create "manifests". It also wants to create dependencies on an assembly-like version of the CRT (C RunTime). Your DLL will load on your development machine when you debug, but it doesn't load on your neighbor's machine when you ask him/her to test. You've got to find and distribute the CRT, and it no longer has a friendly filename or location. This is progress? The only way to make manual deployment of such a DLL feasible is to turn off all the new manifest options when you compile.

This is an example of a larger problem with the complexity of Windows. There are too many moving parts. I swap out my laptop every 2 years. I should be able to XCopy my hard drive to the new machine, log on to the new machine, and just start pounding code. Not so... There are a plethora of cryptic, interdependent settings in the registry that all need to be just so in order for any Microsoft application to launch. So much for XCopy deployment.

My uninstallation of MSVC 2003 is still running. Vista loves to binge on disk space, so it's a constant battle to free up a few gigs. It's been well over an hour of watching the progress bar move about a pixel a per minute. It must be checking dependencies or cleaning up the registry!

Cheers,
Chris

No comments:

Post a Comment

Please keep it short, respectful, and clean!