I’m a big believer in DRY – Don’t Repeat Yourself – in software.
While I try hard to practice this in the code for the Bag of Tricks (BOT), until recently I’ve ignored my project files.
VS handles that, right?
It turns out there is a lot of duplication in proj files. Every one defines constants and output paths. If you’re using Code Contracts, you get a bunch of contract properties all over – sometimes differing in inexplicable ways between debug and release.
I got sick of it. I cleaned it up.
- BuildShared.targets – Shared state across every project. Warning levels, shared build constants, even output path.
- This is great. If I want to change the location of obj and bin, I just change one file now. Super nice.
- Contracts.targets – This defines all of the Code Contracts build parameters.
- WPF4, SL4, WP7.targets – Common code for a given platform. Things like target framework, framework profile, etc. (WPF and SL include Contracts, Phone dosen’t.)
- Now each proj file includes the associated platform proj file and just sets project-specific properties.
- Guids, OutputType (library or exe), root namespace, assembly name, etc.
The downside: if you go hack specific properties via VS, you’ll add a bunch of one-off changes to individual proj files.
…but this is why we use source control, right? I can look at the diffs and ask: are these changes I want to share across projects or things I can just throw-away?
And having all of the shared noise in another place makes parsing the proj file a lot faster.
Take a look at the code. All of the targets are in PixelLab.Common\_targets. (Yeah, a weird place. I’ll explain later.)