Elton Stoneman

  Home  |   Contact  |   Syndication    |   Login
  82 Posts | 0 Stories | 115 Comments | 0 Trackbacks

News

Archives

Post Categories

[Source: http://geekswithblogs.net/EltonStoneman]

FxCop allows you to define rules as having configurable settings, and through the native UI you can override the settings and save them for each FxCop project. This is useful if you want to have a generic set of rules that can be used to enforce differing sets of standards, without having to modify the rule assemblies.

It's not well documented, but you need to implement IConfigurableRule and provide default setting values. There's a straightforward sample on Dennis Forbes' blog, but you can move the IConfigurableRule implementation to a base class and just have the specific setting code in the child class:

Bear in mind that FxCop will instantiate an instance of the rule prior to firing it during analysis, and will cache that instance for all analysis runs, so your configuration code should account for this. Key things to note:

  • Settings are held in two IDictionary objects, representing the default settings and the current settings. In theory any dictionary type will do, but I had problems with using generic dictionaries, so resorted to using Hashtable;
  • Add values to the default setting collection in a static constructor, then use ConfigurationHelper.CopyFromDefault() to copy default settings to the current setting collection. This has to be in a static constructor, lazy-loading the DefaultSettings property won't work;
  • Use ConfigurationHelper.LoadSettings() in your implementation of LoadSettings, to update the current dictionary with saved values from the FxCop project file;
  • Use ConfigurationHelper.SaveSettings() in your SaveSettings implementation to copy the current setting values back to the FxCop project file. FxCop will only call this if the current settings differ from the defaults;
  • There's no event model to notify when current settings have been changed, so if you're caching downstream based on a setting value, you'll need to check the cache is valid before each call.

The need to set up defaults in a static constructor complicates the implementation of the base class. One option is to store a static collection of Hashtables in the base class, keyed by the child class type name (this is the implementation I used in BizTalkCop, full code samples there).

posted on Monday, November 17, 2008 7:41 PM