Another D3 release is up. This time I continued my focus on fundamentals. Some of this is tedious, but as I establish solid mechanics I’m starting to gain some momentum. The theme for today is using every last asset at your disposal to fight the battle to build great software. When I first came to Microsoft a number of years ago, I was given the book Writing Solid Code to help get me on the path to building world-class, reliable software. While the book is a bit dated these days, the key message I took away is as important to me now as it was then:
Writing software is hard. So hard, in fact, that we need to play every trick in the book (and then some) if we’re going to have any hope of really getting it right.
The previous two versions of DPMud were just hacks, but this time around I’m trying to build something that demonstrates how the EF can be used as a key component in software to be proud of. So, I ought to do things right—at least as much as I can given time constraints and everything else.
Often Overlooked Asset #1: Analysis Tools
This weekend I spent some time enabling fxcop and stylecop for D3. Actually I’m using the VSTS code analysis feature rather than fxcop because it’s built in to the VSTS download of VS2010 with really nice integration. Turning it on was a breeze, I just right clicked on each of my projects, chose properties, clicked on the code analysis tab and then checked the Enable Code Analysis on Build box. Actually, the first step was to download and install the VSTS flavor of VS2010 since I had initially just installed VS-Pro. I was happy to find, though, that the web install was able to install VSTS on top of my existing pro install without any trouble and was even smart enough to skip all the minor components that were already on my machine…
The hard part was discovering just how many issues it could find even with the very small amount of code present in D3 so far. As you can see above I’m just using the minimum recommended rules right now, and even with that I had to fix quite a few issues. Most of them were essentially cosmetic things, but it did catch a place where I was doing string concatenation of a SQL query that should have been using a parameter. There wasn’t any user input in sight, so I didn’t really have to worry about an injection attack, but it’s still a much better practice to use parameters wherever possible so I was happy to fix it. At some point I expect that I’ll go back and crank the rule-level up even higher, but there were enough issues when I did that which were more about personal preference than really being super important (like requiring that assembly names begin with a capital letter) that I decided it wasn’t worth the effort just yet.
I also downloaded stylecop and turned it on. It’s a little more work since it’s not part of the core product, but like fxcop it really was surprisingly easy to turn on and then the real work was making the project comply. I’m so glad that I did it now rather than later in the project, because keeping things going as I make incremental changes appears quite easy—the hard part is in the conversion. If you have a large amount of code already, I would still recommend making the switch to these tools, but you might want to checkout the stylecop team blog where there is a post about ways to make sure all new code is checked and then gradually convert older code. Fxcop is probably a bit more difficult but still worth it.
In order to turn on stylecop, I copied the binaries for the tool to a directory under my source control, modified the batch file I load for my development environment to set an environment variable pointing to the directory where stylecop is present. Then I unloaded each csproj, edited the XML and added one import element pointing to the stylecop targets file (I put mine next to the Import element for the standard csharp targets):
<Import Condition="'$(StyleCopPath)' != ''" Project="$(StyleCopPath)\Microsoft.StyleCop.targets" />
I put the condition attribute on it so if you don’t have the environment variable defined, it won’t try to load anything. That way everything builds and works without stylecop. (Code analysis also has the feature that if you don’t have it installed because you have VS-pro or something instead of VSTS then the configuration is just ignored and everything builds fine.) Unfortunately, this same edit needs to be made to each csproj file so the trick is to make sure not to forget this when adding new assemblies in the future.
By default both code analysis and stylecop report things as warnings, but I wanted to make certain everything was fixed so I also added a couple properties to the csproj files that change them into errors rather than warnings:
Asset #2: Check Constraints in the DB
internal partial class SqlDb
partial void Customize()
// Check Constraint which requires that Items live in either a room or on an actor.
this.ExecuteCommand(@"ALTER TABLE [dbo].[Items]
WITH CHECK ADD CONSTRAINT [CK_Item_one_and_only_one_location]
CHECK ((([Room_Id] IS NULL OR [Actor_Id] IS NULL) AND
NOT ([Room_Id] IS NULL AND [Actor_Id] IS NULL)))");
this.ExecuteCommand(@"ALTER TABLE [dbo].[Items] CHECK CONSTRAINT [CK_Item_one_and_only_one_location]");
Asset #3: Unit Testing Your Brains Out