;

Creating a custom StyleCop rule

Posted : Sunday, 31 July 2011 20:51:21

I’ve been working a short-term contract for the last month or so and one of the coding standards for the codebase is not to use implicit variable declaration. The justification for this requirement is that it makes code less readable and could be construed as lazy, I can certainly see this point of view but personally I like them, I find it quicker to write code when you cant remember exactly what the return type of a given method might or the type it self is something like IEnumerable<ICollection<Something ElseWithAReallylongName>>>. I also think it makes code more flexible to implementation changes; when you might change the return type of method to a base class for example. Regardless of my opinion, coding standards are just that and in a team environment they are essential so in this contract there is no place for var! It sounds easy, “just don’t use var” I tell myself but almost invariably, following the end-of-week code review, I get pulled up for littering the code with var. So I was looking for a solution that would enable me to automatically check my code. Another of the coding standards at this particular contract is that all code files must be StyleCop compliant- this struck me as the perfect opportunity to stamp out my use of var (for the duration of this contract at least Winking smile).

So I searched around for a bit to found out how to write custom style cop rules. These two links were really helpful:

http://scottwhite.blogspot.com/2008/11/creating-custom-stylecop-rules-in-c.html

and

http://www.planetgeek.ch/2009/07/19/custom-stylecop-rules/

The first is a really straightforward walkthrough which was child's play to follow but sadly didn’t work when I tried. The second is a two part series which was much more informative but not quite what I was looking for  - I just wanted to drop a custom rule into StyleCop and have it work. According to Scott's post, dropping my new assembly into the StyleCop installation should be all that's required.

I followed Scotts approach (altering his sample rule to a skeleton version of my own called NoVarRuleAnalyzer) but it wouldn't work for me, StyleCop just wouldn’t pick up the rule. To verify if StyleCop has loaded the rule drag the Settings.StyleCop file onto the file named  StyleCopSettingsEditor.exe and you should see something like this:

image

If the new rule has been loaded you should see it appear in whatever group you set in the Name property of the xml metadata file from Scott’s post. I followed all the steps but it just wouldn’t work, I even used reflector to poke about inside the rules assembly that ships with StyleCop to try and find any differences but I couldn't see any. I was getting a bit frustrated when I had a flash of inspiration, the two posts above date from 2008 and 2009 respectively. VisualStudio 2010 defaults to .Net4 but both of these posts pre date .Net4 – I altered the assembly version to 3.5 recompiled, dropped it in the StyleCop directory and bingo:

image

Sweet Smile.

One thing that was starting to irritate me was that in using this approach I had to close VisualStudio and delete my custom rule assembly every time I wanted to make a change to the rule. VisualStudio will load all StyleCop rule assemblies on startup so the files get locked and you have to close VisualStudio to unload them before you can overwrite them. This is where the second post listed above came to the rescue.

In the second part of the planetgeek post, the author Thomas outlines how he broke out the StyleCop execution code into a separate assembly that he uses to unit test his custom StyleCop rules. While this was a bit more effort than I was wanting to spend the validity of his approach is unquestionably sound, particularly if you intend to implement a lot of different rules. What I did take from the post however was a bit of an insight into the structure and makeup of the StyleCop application. The key class as far as executing a particular rule goes is the StyleCopConsole class. By the way I should point out that the SDK for StyleCop is available at StyleCop on CodePlex. So I added a new console application to my solution and created a new class called RuleRunner. The first thing I did was create a class level field to hold a reference to an instance of the StyleCopConsole class, in the constructor I instantiated this reference using the minimum amount of effort/parameters:

   10     public class RuleRunner
   11     {
   12         private StyleCopConsole styleCopConsole;
   13 
   14         public RuleRunner()
   15         {
   16             var settings = Path.GetFullPath("Settings.StyleCop");
   17          

  • (This will not appear on the site)