Tuesday, June 13, 2006

Visual Studio 2005: Adventures in dependent project items

Being a perfectionist programmer today is dangerous to your health. When confronted with the real world, the two (perfectionist and the programmer) tend to be driven into opposite directions, resulting in a split personality. And straying from the well-treaded path of tutorials in the Microsoft world can bring you into unknown perils.

A case in point: Visual Studio (in this case, 2005) has a nice treeview showing the contents of your projects and solutions. In it, dependent files are shown as child nodes of their parents and it all works... Until you try to use this handy mechanism on your own files. Then you notice it's mostly a facade that looks nice but doesn't support anything beyond what's already there.

For example: if, in addition to the *.Design.cs files in which designer-generated code is stored, you want to add your own child file to a component, say *.PublicProperties.cs. How do you add a new child file? You have to edit the .csproj file and add tags. Not nice.

If you double-click your child file it won't behave like the *.Design.cs file. It won't be opened in the source code editor but instead opens the designer - and an empty one, too, because it shows your part of the partial class, not the whole class. It turns out that Visual Studio doesn't really have a clue (or doesn't care) if your file is only part of a multi-file partial class.

So, we draw a conclusion that Visual Studio is hardwired to recognize files named *.Design.cs and not care about anything else, no matter how obvious it is (in other words: it's dumb). This is further confirmed if you try to convert your multi-file class into a visual studio project item template (you know, for the item types that get shown when you click Add->New Item). Your DependendUpon tags will vanish from the template never to return. When you Add->New your multi-part item, the item will show up as several unconnected (and un-parented) files.

Even worse - let's say you want to tidy up your NHibernate projects and have the *.hbm.xml mapping files become children of the persistent classes. No go: the NHibernate mapping will stop working because the compiler will cut off the hbm.xml extension! If you eliminate the DependsUpon relation, it will leave it as is.

So, the conclusion? Leave it. If it's ugly, it's ugly. Can't do a dang thing about it.