65.9K
CodeProject 正在变化。 阅读更多。
Home

编写自己的 FXCOP 自定义规则的 7 个步骤

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (19投票s)

2008年11月4日

CPOL

4分钟阅读

viewsIcon

172635

downloadIcon

1454

使用 FXCOP 编写自己的自定义规则的 7 个步骤。

目录

引言

FXCOP 是一个传奇的工具,它帮助我们使用针对已编译程序集的规则集来自动化代码审查。本文将讨论 FXCOP 的一些基础知识,然后主要关注如何为 FXCOP 添加自定义规则。

FXCOP 基础知识

顾名思义,FXCOP 中的 COP 指的是“警察”。所以它是一个分析工具,它针对 .NET 程序集运行规则,并提供关于违反规则的完整报告。由于它在程序集上运行,因此可以用于任何语言,如 C#、VB.NET 等。您可以 此处 下载 FXCOP 的最新版本。

下图直观地展示了 FXCOP 如何运行规则对程序集进行分析,然后在另一个窗格中显示违反规则的项目。

使用现有规则

使用现有规则非常简单。打开 FXCOP 工具,您会看到两个选项卡:目标选项卡和规则选项卡。目标选项卡用于添加程序集。您可以通过右键单击然后单击“添加目标”来添加程序集 DLL。

需要在第二个选项卡“规则”中选择要运行的规则。所以点击该选项卡,选择必要的规则,然后点击“分析”。

添加自定义规则 - 所有连接对象都应关闭

为了理解自定义规则的概念,我们将以实际示例来说明。我们将做的是,当任何连接对象在方法中打开时,我们将确保它被关闭。如果未关闭,FXCOP 将抛出错误。

步骤 1

要创建自定义规则,第一步是创建一个类库。FXCOP 需要一个 XML 文件来定义规则。XML 文件的格式如下所示。我们将此文件命名为“Connection.XML”。Rule 标记具有 `TypeName` 属性,其中包含类名,即 `ClsCheck`。我们将在稍后创建该类。description 标记定义了在规则违反时应抛出的错误消息。

<?xml version="1.0" encoding="utf-8" ?>
<Rules>
<Rule TypeName="clsCheck" Category="Database" CheckId="Shiv001">
<Name>Connection object Should be closed</Name>
<Description> Connection objects should be closed</Description>
<Owner> Shivprasad Koirala</Owner>
<Url>http://www.questpond.com</Url>
<Resolution> Call the connection close method </Resolution>
<Email></Email>
<MessageLevel Certainty="99"> Warning</MessageLevel>
<FixCategories> Breaking </FixCategories>
</Rule>
</Rules>

第二步

首先,需要引用并导入 FXCOP SDK。所以添加对 `FxCopSdk.DLL` 的引用。您可以在 FXCop 安装的位置找到 `FxCopSdk.dll`。

添加引用后,您需要在类文件中导入该 DLL。

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.FxCop.Sdk;

步骤 3

要定义自定义规则,您需要继承 FXCop 的 `BaseIntrospectionRule` 类。所以下面是继承自 `BaseIntrospectionrule` 类的自定义类 `ClsCheck`。`ClsCheck` 的构造函数非常重要。我们基本上调用父构造函数,需要在其中传递类名和 XML 文件。所以我们传递了 `clsCheck` 类和 `Connection.XML` 文件名。我们还必须重写 `Check` 方法。`Check` 方法在解析每个方法时被调用。如果存在任何问题,我们需要返回一个 `problemcollection` 数组,该数组将在 FXCOP UI 中显示。

public class clsCheck : BaseIntrospectionRule
{
public clsCheck(): base("clsCheck", "MyRules.Connection", typeof(clsCheck).Assembly)
{
}

public override ProblemCollection Check(Member member)
{
…….
……..
}
}

步骤 4

所以第一步,我们将成员转换为 `Method` 对象。我们定义了两个布尔变量,一个指定连接对象已打开,另一个指定连接对象已关闭。

Method method = member as Method;
bool boolFoundConnectionOpened = false;
bool boolFoundConnectionClosed = false;
Instruction objInstr=null;

步骤 5

每个方法都有一个指令集合,这实际上就是实际的代码。所以我们遍历所有指令,检查是否找到 `SQLConnection` 的 `string`。如果是,我们将找到的连接的布尔值设置为 `true`。如果我们发现我们找到了 `'Dbconnection.close'`,我们就将找到的连接的关闭状态设置为 `true`。

for (int i = 0; i < method.Instructions.Count; i++)
{objInstr = method.Instructions[i];
if (objInstr.Value != null)
{
if (objInstr.Value.ToString().Contains("System.Data.SqlClient.SqlConnection"))
{
boolFoundConnectionOpened = true;
}
if (boolFoundConnectionOpened)
{
if(objInstr.Value.ToString().Contains("System.Data.Common.DbConnection.Close"))
{
boolFoundConnectionClosed = true;
}

步骤 6

现在是最后一步。我们检查连接是否已打开,是否已关闭?如果没有,那么我们获取 `connection.xml` 文件中的消息,并将其添加到 problems 集合中。这个 problems 集合被返回给 FXCOP 以进行显示。

if((boolFoundConnectionOpened)&&(boolFoundConnectionClosed ==false))
{
Resolution resolu = GetResolution(new string[] { method.ToString() });
Problems.Add(new Problem(resolu));
}
return Problems;

步骤 7

编译 DLL 后,将 DLL 添加为规则并运行“分析项目”按钮。下面是经过分析的项目以及“objConnection”对象,该对象已打开但从未关闭。

public void addInvoiceDetails(int intInvoiceid_fk,
int intCustomerId,
int intProductid_fk,
double dblTotalAmount,
double dblTotalAmountPaid)
{
SqlConnection objConnection = new SqlConnection();
}

您可以在输出中看到方法名称是如何显示的,以及从 `connection.xml` 文件读取的解析结果。

如需进一步阅读,请观看以下面试准备视频和分步视频系列。

© . All rights reserved.