自定义FxCop规则示例之一:AvoidICloneableImplementation

2年前的Tech Ed China上就有过FxCop的介绍,当时译为“框架警察”。关于FxCop的介绍和若干规则示例,可以参考John Robbins所写的Bad Code? FxCop to the RescueThree Vital FXCop Rules文章。本系列将由浅入深的解释定制FxCop的常用方式和技巧。

设计新类时要避免实现ICloneableBlog中仅仅解释了其原因。对于Design Guideline的实施,可以经常得到FxCop的帮助。既然FxCop自带的规则还没有包括对这一设计指导的检查,让我们自己来写一个这样的规则。全部步骤如下。使用的是.NET框架1.1VS2003FxCop 1.312版本,注意FxCop规则编程现在并没有得到官方支持。如果以后版本API发生变化,我会对示例程序有选择的更新。

  1. 下载FxCop 1.312: http://www.gotdotnet.com/team/fxcop/ 选择FxCop for .NET 1.1.
  2. 安装FxCop 1.312, 其缺省安装在“%ProgramFiles%"Microsoft FxCop 1.312”文件夹下。注意其中包括的FxCopSdk.dllMicrosoft.Cci.DLL2个程序集(assembly)。我们的规则项目需要引用它们。
  3. 启动FxCop, 留意到在Rules Tab下所有预先提供的Rules.
  4. 设计新类时要避免实现ICloneable中提供的测试用例编译成为一个Class library起名为FxCopRuleTests
  5. 通过菜单,工具栏或者Ctrl+Shift+A以增加Target,即这些Rule将检查的程序集。添加FxCopRuleTests
  6. 通过菜单,工具栏或者F5开始分析。结果有7violation messages,但是没有设计新类时要避免实现ICloneable相关的消息。我们现在就开始写这样的一个FxCop Rule.
  7. 使用VS2003创建新的Class Library项目起名CustomFxCopRules.
  8. 删除IDE创建的Class1.csAssemblyInfo.cs.
  9. 添加对FxCopSdk.dllMicrosoft.Cci.DLL的引用
  10. 增加一个类文件叫做AvoidICloneableImplementation.cs.
  11. 添加一个命名为RuleInfo.xmlXML文件,设置其Build ActionEmbedded Resource.
  12. 使用如下的代码,实现这一简单的FxCop Rule,编译后通过菜单,工具栏或者Ctrl+R加入FxCopRule之中,再运行FxCop看到正确结果。(提示,可以uncheck所有FxCop自带规则以减少干扰。

这是RuleInfo.xml

<?xmlversion="1.0"encoding="utf-8"?>

<RulesFriendlyName="Custom FxCop Rules">

 <RuleTypeName="AvoidICloneableImplementation"Category="ZhanboBlog.Demo"CheckId="ZB001">

    <Name>Avoid ICloneable Implementation</Name>

    <Description>ICloneable could be used to return either deep copy or shallow copy, and is therefore not useful.</Description>

    <Url>http://blog.joycode.com/zhanbos/archive/2005/03/13/45707.aspx</Url>

    <Resolution>Type '{0}' Implements ICloneable, which should be avoided.</Resolution>

    <Email/>

    <MessageLevelCertainty="99">Error</MessageLevel>

    <FixCategories>Breaking</FixCategories>

    <Owner/>

 </Rule>

</Rules>

这是AvoidICloneableImplementation.cs

using System;

using Microsoft.Cci;

using Microsoft.Tools.FxCop.Sdk;

using Microsoft.Tools.FxCop.Sdk.Introspection;

namespace ZhanboBlog.Demo.CustomRules

{

 ///<summary>

 /// Do not implement ICloneable interface

 ///</summary>

 public class AvoidICloneableImplementation : BaseIntrospectionRule

 {

    public AvoidICloneableImplementation() :

      base("AvoidICloneableImplementation", "ZhanboBlog.Demo.CustomRules.RuleInfo", typeof(AvoidICloneableImplementation).Assembly)

    {

    }

    public override ProblemCollection Check(TypeNode type)

    {

      if (DoesImplementICloneable(type.Interfaces))

      {

        Resolution resolution = GetResolution(RuleUtilities.Format(type));

        Problem newProblem = new Problem(resolution, type);

        Problems.Add(newProblem);

        return Problems;

      }

      return null;

    }

    private bool DoesImplementICloneable(InterfaceList interfaceList)

    {

      for(int i = 0; i < interfaceList.Length; i++)

      {

        if (interfaceList[i] == SystemTypes.ICloneable)

        {

          return true;

        }

      }

      return false;

    }

 }

}

如果您对某些代码有疑惑,可以留下评论我会在下一次Blog中提供必须的解释。通过实践会加深认识。您有什么希望增加FxCop规则检查的情形也欢迎提出,作为以后FxCop示例的参考。

posted on 2007-09-29 15:11  RIVERSPIRIT  阅读(1048)  评论(1编辑  收藏  举报