My current project has stringent requirements across the board, including that of a highly consistent coding style. This is completely understandable because the client will be taking over maintenance and long-term support sometime after we’ve shipped. As such, they want to feel comfortable that their developers won’t be handed a steaming pile of code poo to polish.
One of the tools I thought might help us with this problem is StyleCop. This tool can analyze your code and flag any issues related to style. My initial suspicion was that StyleCop would annoy the heck out of me in about 10 seconds flat. It would whinge about missing file headers, the number of blank lines between code blocks, and even missing API documentation on private members. And it did do just that.
But something strange happened after a while: I stopped caring.
But not in a bad way. I just let the tool make these micro-decisions for me and instead concentrated on more important things like – you know – making the product actually work. If it told me I needed a blank line between my property getter and setter, I just did it – no questions asked. There was no nagging worry that I would do it differently elsewhere, or that some future developer on the project would, because the tool simply wouldn’t allow you to.
I’ve been able to get StyleCop integrated to an extent that I am very happy with:
- It runs every time I build, whether it’s on my machine or the build machine. And it does not need to be installed on the developer’s machine (or the build server)
- Any problems StyleCop reports prevent the build from succeeding (i.e. any problems are errors, not warnings)
- Less important projects are excluded from StyleCop altogether, or have relaxed rules (such as for unit test projects, which don’t need API documentation)
- Modifications to StyleCop settings are stored in central settings files and shared across projects. For example, I have a TestProjectSettings.StyleCop file, which contains settings for unit and integration test projects. If I disable a rule for one test project, it is disabled for all of them
The intent of this post is not to help you set StyleCop up with MSBuild. There are other resources out there that show you how to do that. I’m more interested in encouraging people to try this tool out. The more people that use it, the more it will be improved. And there is plenty of scope for improvement, as I’ll discuss shortly. If you’ve held off trying out this tool because you had bad experiences with it earlier in its short history, or because you think it has little to offer, perhaps it’s time to rethink.
So, what are the problems I’ve had using StyleCop? The biggest problem is that it’s lazy. It will happily report style problems to you any day of the week – even Sunday – but it refuses to lift a finger when it comes to rectifying said problems. This can be very irritating at first, but over time I have found myself preemptively and reflexively avoiding StyleCop’s wrath by writing code that conforms more and more to the default rule set.
The next problem is that of the default rule set. In adopting StyleCop I made it quite clear to my client that doing so implies either accepting the default rules, or spending a significant amount of time writing custom ones (time I don’t have). I can almost guarantee you won’t like all the default rules. Some of them will make you cringe, whilst others may make you downright furious. Of course, you can disable or tweak those rules that really get your goat.
Finally, StyleCop is particularly frustrating when you’re just wanting to try out a piece of code quickly in your project. There’s no built-in mechanism to demarcate a block of code as temporary and exempt it from style checks. Undef’ing the CODE_ANALYSIS symbol seems to do nothing, and SuppressMessage does not have any wildcard support. Therefore, you either need to move your scratch code into a temporary project, or waste time placating StyleCop.
UPDATE: As noted by wekempf in the comment below, you can wrap experimental code in a region with “generated code” in its name. This works even when you have the disallow all regions StyleCop rule enabled!
But for all its warts, I still feel somewhat liberated by StyleCop. No longer do I worry about whether I have the correct spacing, line breaks, or bracket placement in my source. I let the tool worry about that for me. And I feel as though spending the extra brain cycles on more important concerns is a win for both myself and my client.
Note that I am the only .NET developer on my project at the moment, so I can’t really comment on how well this would work with a team. I can’t really see it being an issue if everyone agrees that no rules should be disabled or suppressed without due justification and discussion. Some developers are sure to balk at the idea of having to conform to a particular style, but that’s only because it’s not their style. Heck, I was hesitant at first to make dramatic changes to my style (I prefer tabs, for example), but I quickly adjusted when I saw the benefits of the tool.
So next time you’re embarking on a new project, consider integrating StyleCop right from the get-go. The short term may be painful, but I think you’ll appreciate the decision in the long term.
The
But suppose we wanted to change the Add and Delete buttons to
The thing is, routed commands are not always a great fit for MVVM development. Typically the logic for your command execution belongs in the view model. For example, suppose you have a
If you think about it, all we really want to do is have a command that – when executed – invokes a method in our view model. And when the command is queried for its executable status, it executes a different method in the view model. To continue our customer example, that command might be associated with a