每个开发人员现在应该下载的十种必备工具

每个开发人员现在应该下载的十种必备工具

发布日期: 7/20/2004 | 更新日期: 7/20/2004

本文自发布以来已经增加了新信息。

请参阅下面的编辑更新。

本文讨论:

用于编写单元测试的 NUnit

用于创建代码文档资料的 NDoc

用于生成解决方案的 NAnt

用于生成代码的 CodeSmith

用于监视代码的 FxCop

用于编译少量代码的 Snippet Compiler

两种不同的转换器工具:ASP.NET 版本转换器和 Visual Studio .NET 项目转换器

用于生成正则表达式的 Regulator

用于分析程序集的 .NET Reflector

本文使用了下列技术:

.NET、C# 或 Visual Basic .NET、Visual Studio .NET

除非您使用能够获得的最佳工具,否则您无法期望生成一流的应用程序。除了像 Visual Studio®.NET 这样的著名工具以外,还可以从 .NET 社区获得许多小型的、不太为人所知的工具。在本文中,我将向您介绍一些目前可以获得的、面向 .NET 开发的最佳免费工具。我将引导您完成一个有关如何使用其中每种工具的快速教程 — 一些工具在许多时候可以使您节约一分钟,而另一些工具则可能彻底改变您编写代码的方式。因为我要在本篇文章中介绍如此之多的不同工具,所以我无法详尽讨论其中每种工具,但您应该了解到有关每种工具的足够信息,以便判断哪些工具对您的项目有用。

本页内容
Snippet CompilerSnippet Compiler
RegulatorRegulator
CodeSmithCodeSmith
生成自定义模板生成自定义模板
NUnitNUnit
编写 NUnit 测试编写 NUnit 测试
FxCopFxCop
Lutz Roeder 的 .NET ReflectorLutz Roeder 的 .NET Reflector
NDocNDoc
NAntNAnt
实际运行的 NAnt实际运行的 NAnt
转换工具转换工具
小结小结

Snippet Compiler

Snippet Compiler 是一个基于 Windows® 的小型应用程序,您可以通过它来编写、编译和运行代码。如果您具有较小的代码段,并且您不希望为其创建完整的 Visual Studio .NET 项目(以及伴随该项目的所有文件),则该工具将很有用。

例如,假设我希望向您说明如何从 Microsoft?.NET 框架中启动另一个应用程序。在 Snippet Compiler 中,我将通过新建一个能够创建小型控制台应用程序的文件开始。可以在该控制台应用程序的 Main 方法内部创建代码片段,而这正是我要在这里做的事情。下面的代码片段演示了如何从 .NET 框架中创建记事本实例:

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName= "notepad.exe";
proc.Start();
proc.WaitForExit();

当然该代码片段本身无法编译,而这正是 Snippet Compiler 的用武之地。图 1 显示了 Snippet Compiler 中的这一代码示例。


1 Snippet Compiler

要测试该代码片段,只须按 play(运行)按钮(绿色三角形),它就会在调试模式下运行。该代码片段将生成一个弹出式控制台应用程序,并且将显示记事本。当您关闭记事本时,该控制台应用程序也将关闭。

就我个人而言,我是在尝试为某位向我求助的人士创建一个小型示例时,才发现 Snippet Compiler 是如此宝贵的 — 如果不使用该工具,则我通常必须新建一个项目,确保每个部分都能编译通过,然后将代码片段发送给求助者,并删除该项目。Snippet Compiler 使得这一过程变得更加容易、更加愉快。

Snippet Compiler 由 Jeff Key 编写,并且可以从 http://www.sliver.com/dotnet/SnippetCompiler 下载。

Regulator

Regulator 是最后一个添加到我的头等工具清单中的。它是一种很有特色的工具,能够使生成和测试正则表达式变得很容易。人们对正则表达式重新产生了兴趣,因为它们在 .NET 框架中受到很好的支持。正则表达式用来基于字符、频率和字符顺序定义字符串中的模式。它们最常见的用途是作为验证用户输入有效性的手段或者作为在较大字符串中查找字符串的方法 — 例如,在 Web 页上查找 URL 或电子邮件地址。

Regulator 使您可以输入一个正则表达式以及一些针对其运行该表达式的输入内容。这样,在应用程序中实现该正则表达式之前,您可以了解它将产生什么效果以及它将返回哪些种类的匹配项。图 2 显示了带有简单正则表达式的 Regulator。

文档中包含该正则表达式 — 在该示例中,它是 [0-9]*,应该匹配一行中任意数量的数字。右下侧的框中含有针对该正则表达式的输入,而左下侧的框显示了该正则表达式在输入内容中找到的匹配项。在这样的单独应用程序中编写和测试正则表达式,要比尝试在您的应用程序中处理它们容易得多。

Regulator 中的最佳功能之一是能够在 regexlib.com 搜索联机正则表达式库。例如,如果您在搜索框中输入字符串“phone”,您将找到 20 种以上能够匹配各种电话号码的不同的正则表达式,包括用于英国、澳大利亚的表达式以及其他许多电话号码。Regulator 由 Roy Osherove 编写,并且可以在 http://royo.is-a-geek.com/regulator 下载。

CodeSmith

CodeSmith 是一种基于模板的代码生成工具,它使用类似于 ASP.NET 的语法来生成任意类型的代码或文本。与其他许多代码生成工具不同,CodeSmith 不要求您订阅特定的应用程序设计或体系结构。使用 CodeSmith,可以生成包括简单的强类型集合和完整应用程序在内的任何东西。

当您生成应用程序时,您经常需要重复完成某些特定的任务,例如编写数据访问代码或者生成自定义集合。CodeSmith 在这些时候特别有用,因为您可以编写模板自动完成这些任务,从而不仅提高您的工作效率,而且能够自动完成那些最为乏味的任务。CodeSmith 附带了许多模板,包括对应于所有 .NET 集合类型的模板以及用于生成存储过程的模板,但该工具的真正威力在于能够创建自定义模板。为了使您能够入门,我将快速介绍一下如何生成自定义模板。

生成自定义模板

CodeSmith 模板只是一些可以在任意文本编辑器中创建的文本文件。它们的唯一要求是用 .cst 文件扩展名来保存它们。我将要生成的示例模板将接受一个字符串,然后基于该字符串生成一个类。创建模板的第一步是添加模板头,它可声明模板的语言、目标语言以及简要模板说明:

<%@ CodeTemplate Language="C#"    
   TargetLanguage="C#" 
   Description="Car Template" %>


模板的下一部分是属性声明,在这里可声明将在模板每次运行时指定的属性。就该模板而言,我要使用的唯一属性只是一个字符串,因此属性声明如下所示:

<%@ Property Name="ClassName" Type="String" Category="Context"
    Description="Class Name" %>
 

该属性声明将使 ClassName 属性出现在 CodeSmith 属性窗口中,以便可以在模板运行时指定它。下一步是实际生成模板主体,它非常类似于用 ASP.NET 进行编码。您可以在图 3 中查看该模板的主体。[编辑更新 — 6/16/2004:图 3 中的代码已被更新,以便对多线程操作保持安全。]

正如您所见,该模板接受字符串输入并使用该类名生成单独的类。在模板主体中,使用与 ASP.NET 中相同的起始和结束标记。在该模板中,我只是插入属性值,但您还可以在这些标记内部使用任意类型的 .NET 代码。在该模板完成之后,您就可以通过双击它或者从 CodeSmith 应用程序中打开它将其加载到 CodeSmith 中。图 4 显示了已经加载到 CodeSmith 中的该模板。

您可以看到左侧的属性正是我在该模板中声明的属性。如果我输入“SingletonClass”作为类名,并单击 Generate 按钮,则将生成图 3 的底部显示的类。

CodeSmith 使用起来相当容易,如果能够正确应用,则可以产生一些令人难以置信的结果。面向代码生成的应用程序中最常见的部分之一是数据访问层。CodeSmith 包括一个名为 SchemaExplorer 的特殊的程序集,可用来从表、存储过程或几乎任何其他 SQL Server? 对象生成模板。

CodeSmith 由 Eric J. Smith 编写,并且可以在 http://www.ericjsmith.net/codesmith 下载。

NUnit

NUnit 是为 .NET 框架生成的开放源代码单元测试框架。NUnit 使您可以用您喜欢的语言编写测试,从而测试应用程序的特定功能。当您首次编写代码时,单元测试是一种测试代码功能的很好方法,它还提供了一种对应用程序进行回归测试的方法。NUnit 应用程序提供了一个用于编写单元测试的框架,以及一个运行这些测试和查看结果的图形界面。

编写 NUnit 测试

作为示例,我将测试 .NET 框架中 Hashtable 类的功能,以确定是否可以添加两个对象并且随后检索这些对象。我的第一步是添加对 NUnit.Framework 程序集的引用,该程序集将赋予我对 NUnit 框架的属性和方法的访问权。接下来,我将创建一个类并用 TestFixture 属性标记它。该属性使 NUnit 可以知道该类包含 NUnit 测试:

using System;
using System.Collections;
using NUnit.Framework;

namespace NUnitExample
{
    [TestFixture]
    public class HashtableTest {
        public HashtableTest() {
            
        }
    }
}

下一步,我将创建一个方法并用 [Test] 属性标记它,以便 NUnit 知道该方法是一个测试。然后,我将建立一个 Hashtable 并向其添加两个值,再使用 Assert.AreEqual 方法查看我是否可以检索到与我添加到 Hashtable 的值相同的值,如下面的代码所示:

[Test]
public void HashtableAddTest()
{
    Hashtable ht = new Hashtable();
            
    ht.Add("Key1", "Value1");
    ht.Add("Key2", "Value2");

    Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!");
    Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!");
}

这将确认我可以首先向 Hashtable 中添加值并随后检索相应的值 — 这是一个很简单的测试,但能够表现 NUnit 的功能。存在许多测试类型以及各种 Assert 方法,可使用它们来测试代码的每个部分。

要运行该测试,我需要生成项目,在 NUnit 应用程序中打开生成的程序集,然后单击 Run 按钮。图 5 显示了结果。当我看到那个大的绿色条纹时,我有一种兴奋和头晕的感觉,因为它让我知道测试已经通过了。这个简单的示例表明 NUnit 和单元测试是多么方便和强大。由于能够编写可以保存的单元测试,并且每当您更改代码时都可以重新运行该单元测试,您不仅可以更容易地检测到代码中的缺陷,而且最终能够交付更好的应用程序。


5 NUnit

NUnit 是一个开放源代码项目,并且可以从 http://www.nunit.org 下载。还有一个优秀的 NUnit Visual Studio .NET 外接程序,它使您可以直接从 Visual Studio 中运行单元测试。您可以在 http://sourceforge.net/projects/nunitaddin 找到它。有关 NUnit 及其在测试驱动开发中的地位的详细信息,请参阅文章“Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques”(MSDN ®Magazine 2004 年 4 月刊)。

FxCop

.NET 框架非常强大,这意味着存在创建优秀应用程序的极大可能,但是也同样存在创建劣质程序的可能。FxCop 是有助于创建更好的应用程序的工具之一,它所采用的方法是:使您能够分析程序集,并使用一些不同的规则来检查它是否符合这些规则。FxCop 随附了由 Microsoft 创建的固定数量的规则,但您也可以创建并包括您自己的规则。例如,如果您决定所有的类都应该具有一个不带任何参数的默认构造函数,则可以编写一条规则,以确保程序集的每个类上都具有一个构造函数。这样,无论是谁编写该代码,您都将获得一定程度的一致性。如果您需要有关创建自定义规则的详细信息,请参阅 John Robbins 的有关该主题的 Bugslayer 专栏文章(MSDN ® Magazine 2004 年 6 月刊)。

那么,让我们观察一下实际运行的 FxCop,并且看一下它在我一直在处理的 NUnitExample 程序集中找到哪些错误。当您打开 FxCop 时,您首先需要创建一个 FxCop 项目,然后向其添加您要测试的程序集。在将该程序集添加到项目以后,就可以按 Analyze,FxCop 将分析该程序集。图 6 中显示了在该程序集中找到的错误和警告。

FxCop 在我的程序集中找到了几个问题。您可以双击某个错误以查看详细信息,包括规则说明以及在哪里可以找到更多信息。(您可以做的一件有趣的事情是在框架程序集上运行 FxCop 并查看发生了什么事情。)

FxCop 可以帮助您创建更好的、更一致的代码,但它无法补偿低劣的应用程序设计或非常简单拙劣的编程。FxCop 也不能替代对等代码检查,但是因为它可以在进行代码检查之前捕获大量错误,所以您可以花费更多时间来解决严重的问题,而不必担心命名约定。FxCop 由 Microsoft 开发,并且可以从 http://www.gotdotnet.com/team/fxcop 下载。

Lutz Roeder 的 .NET Reflector

下一个必不可少的工具称为 .NET Reflector,它是一个类浏览器和反编译器,可以分析程序集并向您展示它的所有秘密。.NET 框架向全世界引入了可用来分析任何基于 .NET 的代码(无论它是单个类还是完整的程序集)的反射概念。反射还可以用来检索有关特定程序集中包含的各种类、方法和属性的信息。使用 .NET Reflector,您可以浏览程序集的类和方法,可以分析由这些类和方法生成的 Microsoft 中间语言 (MSIL),并且可以反编译这些类和方法并查看 C# 或 Visual Basic ®.NET 中的等价类和方法。

为了演示 .NET Reflector 的工作方式,我将加载和分析前面已经显示的 NUnitExample 程序集。图 7 显示了 .NET Reflector 中加载的该程序集。


7 NUnitExample 程序集

在 .NET Reflector 内部,有各种可用来进一步分析该程序集的工具。要查看构成某个方法的 MSIL,请单击该方法并从菜单中选择 Disassembler。

除了能够查看 MSIL 以外,您还可以通过选择 Tools 菜单下的 Decompiler 来查看该方法的 C# 形式。通过在 Languages 菜单下更改您的选择,您还可以查看该方法被反编译到 Visual Basic .NET 或 Delphi 以后的形式。以下为 .NET Reflector 生成的代码:

public void HashtableAddTest()
{ 
    Hashtable hashtable1;
    hashtable1 = new Hashtable();
    hashtable1.Add("Key1", "Value1");
    hashtable1.Add("Key2", "Value2");
    Assert.AreEqual("Value1", hashtable1["Key1"], 
       "Wrong object returned!");
    Assert.AreEqual("Value2", hashtable1["Key2"],
       "Wrong object returned!");
}

前面的代码看起来非常像我为该方法实际编写的代码。以下为该程序集中的实际代码:

public void HashtableAddTest()
{
    Hashtable ht = new Hashtable();
            
    ht.Add("Key1", "Value1");
    ht.Add("Key2", "Value2");

    Assert.AreEqual("Value1", ht["Key1"],
        "Wrong object returned!");
    Assert.AreEqual("Value2", ht["Key2"],
        "Wrong object returned!");
}

尽管上述代码中存在一些小的差异,但它们在功能上是完全相同的。

虽然该示例是一种显示实际代码与反编译代码之间对比的好方法,但在我看来,它并不代表 .NET Reflector 所具有的最佳用途 — 分析 .NET 框架程序集和方法。.NET 框架提供了许多执行类似操作的不同方法。例如,如果您需要从 XML 中读取一组数据,则存在多种使用 XmlDocument、XPathNavigator 或 XmlReader 完成该工作的不同方法。通过使用 .NET Reflector,您可以查看 Microsoft 在编写数据集的 ReadXml 方法时使用了什么,或者查看他们在从配置文件读取数据时做了哪些工作。.NET Reflector 还是一个了解以下最佳实施策略的优秀方法:创建诸如 HttpHandlers 或配置处理程序之类的对象,因为您可以了解到 Microsoft 工作组实际上是如何在框架中生成这些对象的。

.NET Reflector 由 Lutz Roeder 编写,并且可以从 http://www.aisto.com/roeder/dotnet 下载。

NDoc

编写代码文档资料几乎总是一项令人畏惧的任务。我所说的不是早期设计文档,甚至也不是更为详细的设计文档;我说的是记录类上的各个方法和属性。NDoc 工具能够使用反射来分析程序集,并使用从 C# XML 注释生成的 XML 自动为代码生成文档资料。XML 注释仅适用于 C#,但有一个名为 VBCommenter 的 Visual Studio .NET Power Toy,它能够为 Visual Basic .NET 完成类似的工作。此外,下一版本的 Visual Studio 将为更多语言支持 XML 注释。

使用 NDoc 时,您仍然在编写代码的技术文档,但您是在编写代码的过程中完成了文档编写工作(在 XML 注释中),而这更容易忍受。使用 NDoc 时,第一步是为您的程序集打开 XML 注释生成功能。右键单击该项目并选择 Properties | Configuration Properties | Build,然后在 XML Documentation File 选项中输入用于保存 XML 文件的路径。当该项目生成时,将创建一个 XML 文件,其中包含所有 XML 注释。下面是 NUnit 示例中的一个用 XML 编写了文档的方法:

/// <summary>
/// This test adds a number of values to the Hashtable collection 
/// and then retrieves those values and checks if they match.
/// </summary>
[Test]
public void HashtableAddTest()
{
    //Method Body Here
}

有关该方法的 XML 文档资料将被提取并保存在 XML 文件中,如下所示:

<member name="M:NUnitExample.HashtableTest.HashtableAddTest">
  <summary>This test adds a number of values to the Hashtable collection
    and then retrieves those values and checks if they match.</summary> 
</member>

NDoc 使用反射来考察您的程序集,然后读取该文档中的 XML,并且将它们进行匹配。NDoc 使用该数据来创建任意数量的不同文档格式,包括 HTML 帮助文件 (CHM)。在生成 XML 文件以后,下一步是将程序集和 XML 文件加载到 NDoc 中,以便可以对它们进行处理。通过打开 NDoc 并单击 Add 按钮,可以容易地完成该工作。

在将程序集和 XML 文件加载到 NDoc 中并且使用可用的属性范围自定义输出以后,单击 Generate 按钮将启动生成文档资料的过程。使用默认的属性,NDoc 可以生成一些非常吸引人并且实用的 .html 和 .chm 文件,从而以快速有效的方式自动完成原来非常乏味的任务。

NDoc 是一个开放源代码项目,并且可以从 http://ndoc.sourceforge.net 下载。

NAnt

NAnt 是一个基于 .NET 的生成工具,与当前版本的 Visual Studio .NET 不同,它使得为您的项目创建生成过程变得非常容易。当您拥有大量从事单个项目的开发人员时,您不能依赖于从单个用户的座位进行生成。您也不希望必须定期手动生成该项目。您更愿意创建每天晚上运行的自动生成过程。NAnt 使您可以生成解决方案、复制文件、运行 NUnit 测试、发送电子邮件,等等。遗憾的是,NAnt 缺少漂亮的图形界面,但它的确具有可以指定应该在生成过程中完成哪些任务的控制台应用程序和 XML 文件。注意,MSBuild(属于 Visual Studio 2005 的新的生成平台)为每种健壮的生成方案进行了准备,并且由基于 XML 的项目文件以类似的方式驱动。

实际运行的 NAnt

在该示例中,我将为前面创建的 NUnitExample 解决方案创建一个 NAnt 版本文件。首先,我需要创建一个具有 .build 扩展名的 XML 文件,将其放在我的项目的根目录中,然后向该文件的顶部添加一个 XML 声明。我需要添加到该文件的第一个标记是 project 标记: 

<?xml version="1.0"?>
<project name="NUnit Example" default="build" basedir=".">
    <description>The NUnit Example Project</description>
</project>



项目标记还用于设置项目名称、默认目标以及基目录。Description 标记用于设置该项目的简短说明。

接下来,我将添加 property 标记,该标记可用于将设置存储到单个位置(随后可以从文件中的任意位置访问该位置)。在该例中,我将创建一个名为 debug 的属性,我可以随后将其设置为 true 或 false,以反映我是否要在调试配置下编译该项目。(最后,这一特定属性并未真正影响如何生成该项目;它只是您设置的一个变量,当您真正确定了如何生成该项目时将读取该变量。)

接下来,我需要创建一个 target 标记。一个项目可以包含多个可在 NAnt 运行时指定的 target。如果未指定 target,则使用默认 target(我在 project 元素中设置的 target)。在该示例中,默认 target 是 build。让我们观察一下 target 元素,它将包含大多数生成信息:

<target name="build" description="compiles the source code">
</target>
在 target 元素内,我将把 target 的名称设置为 build,并且创建有关该 target 将做哪些工作的说明。我还将创建一个 csc 元素,该元素用于指定应该传递给 csc C# 编译器的数据。让我们看一下该 csc 元素:
<csc target="library" output="./bin/debug/NUnitExample.dll" 
    debug="${debug}">
<references>
    <includes name="C:/program files/NUnit V2.1/bin/NUnit.Framework.dll"/>
</references>
    <sources>
       <includes name="HashtableTest.cs"/>
    </sources>
</csc>

首先,我必须设置该 csc 元素的 target。在该例中,我将创建一个 .dll 文件,因此我将 target 设置为 library。接下来,我必须设置 csc 元素的 output,它是将要创建 .dll 文件的位置。最后,我需要设置 debug 属性,它确定了是否在调试中编译该项目。因为我在前面创建了一个用于存储该值的属性,所以我可以使用下面的字符串来访问该属性的值:${debug}。Csc 元素还包含一些子元素。我需要创建两个元素:references 元素将告诉 NAnt 需要为该项目引用哪些程序集,sources 元素告诉 NAnt 要在生成过程中包含哪些文件。在该示例中,我引用了 NUnit.Framework.dll 程序集并包含了 HashtableTest.cs 文件。图 8 中显示了完整的生成文件。(您通常还要创建一个干净的 target,用于删除生成的文件,但为了简洁起见,我已经将其省略。)

要生成该文件,我需要转到我的项目的根目录(生成文件位于此处),然后从该位置执行 nant.exe。如果生成成功,您可以在该应用程序的 bin 目录中找到 .dll 和 .pdb 文件。尽管使用 NAnt 肯定不像在 Visual Studio 中单击 Build 那样简单,但它仍然是一种非常强大的工具,可用于开发按自动计划运行的生成过程。NAnt 还包括一些有用的功能,例如能够运行单元测试或者复制附加文件(这些功能没有受到当前 Visual Studio 生成过程的支持)。

NAnt 是一个开放源代码项目,并且可以从 http://nant.sourceforge.net 下载。

转换工具

我已经将两个独立的工具合在一起放在标题“转换工具”下面。这两个工具都非常简单,但又可能极为有用。第一个工具是 ASP.NET 版本转换器,它可用于转换 ASP.NET(虚拟目录在它下面运行)的版本。第二个工具是 Visual Studio Converter,它可用于将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003。

当 IIS 处理请求时,它会查看正在请求的文件的扩展名,然后基于该 Web 站点或虚拟目录的扩展名映射,将请求委派给 ISAPI 扩展或者自己处理该请求。这正是 ASP.NET 的工作方式;将为所有 ASP.NET 扩展名注册扩展名映射,并将这些扩展名映射导向 aspnet_isapi.dll。这种工作方式是完美无缺的,除非您安装了 ASP.NET 1.1 — 它会将扩展名映射升级到新版本的 aspnet_isapi.dll。当在 ASP.NET 1.0 上生成的应用程序试图用 1.1 版运行时,这会导致错误。要解决该问题,可以将所有扩展名映射重新转换到 1.0 版的 aspnet_isapi.dll,但是由于有 18 种扩展名映射,所以手动完成这一工作将很枯燥。这正是 ASP.NET 版本转换器可以发挥作用的时候。使用这一小型实用工具,可以转换任何单个 ASP.NET 应用程序所使用的 .NET 框架的版本。


9 ASP.NET 版本转换器

图 9 显示了实际运行的 ASP.NET 版本转换器。它的使用方法非常简单,只须选择相应的应用程序,然后选择您希望该应用程序使用的 .NET 框架版本。该工具随后将使用 aspnet_regiis.exe 命令行工具将该应用程序转换到所选版本的框架。随着将来版本的 ASP.NET 和 .NET 框架的发布,该工具将变得更为有用。

ASP.NET 版本转换器由 Denis Bauer 编写,并且可以从 http://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx 下载。

Visual Studio .NET 项目转换器(参见图 10)非常类似于 ASP.NET 版本转换器,区别在于它用于转换 Visual Studio 项目文件的版本。尽管在 .NET 框架的 1.0 版和 1.1 版之间只有很小的差异,但一旦将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003,将无法再把它转换回去。虽然这在大多数时候可能不会成为问题(因为在 .NET 框架 1.0 版和 1.1 版之间几乎没有什么破坏性的更改),但在某些时刻您可能需要将项目转换回去。该转换器可以将任何解决方案或项目文件从 Visual Studio 7.1 (Visual Studio .NET 2003) 转换到 Visual Studio 7.0 (Visual Studio .NET 2002),并在必要时进行反向转换。


10 Visual Studio .NET 项目转换器

Visual Studio .NET 项目转换器由 Dacris Software 编写。该工具可以从 http://www.codeproject.com/macro/vsconvert.asp 下载。

小结

本文采用走马观花的方式介绍了上述工具,但我已经试图起码向您提供足够的信息以激起您的好奇心。我相信本文已经让您在某种程度上领悟了几个免费工具,您可以立即开始使用这些工具来编写更好的项目。同时,我还要敦促您确保自己拥有所有其他可以获得的合适工具,无论是最新版本的 Visual Studio、功能强大的计算机还是免费的实用工具。拥有合适的工具将使一切变得大不相同。

James Avery 是一位使用 .NET 和其他 Microsoft 技术的顾问。他已经撰写了许多书籍和文章,他的最新著作是《ASP.NET Setup and Configuration Pocket Reference》(Microsoft Press, 2003)。您可以通过 javery@infozerk.com 向他发送电子邮件,并且在 http://www.dotavery.com/blog 阅读他的网络日记。

本文摘自 MSDN Magazine2004 年 7 月刊。

Ten Must-Have Tools Every Developer Should Download Now

 

This article discusses:

  • NUnit to write unit tests
  • NDoc to create code documentation
  • NAnt to build your solutions
  • CodeSmith to generate code
  • FxCop to police your code
  • Snippet Compiler to compile small bits of code
  • Two different switcher tools, the ASP.NET Version Switcher and the Visual Studio .NET Project Converter
  • Regulator to build regular expressions
  • .NET Reflector to examine assemblies
 


ou cannot expect to build a first-class application unless you use the best available tools. Besides well-known tools such as Visual Studio® .NET, there are a multitude of small, lesser-known tools available from the .NET community. In this article, I'm going to introduce you to some of the best free tools available today that target .NET development. I'll walk you through a quick tutorial of how to use each of them, some of which will save you a minute here and there, while others may completely change the way that you write code. Because I am squeezing so many different tools into this single article, I will not be able to cover each of them extensively, but you should learn enough about each to decide which tools are useful for your projects.

Snippet Compiler
  The Snippet Compiler is a small Windows®-based application that allows you to write, compile, and run code. This tool is useful if you have small pieces of code for which you don't want to create an entire Visual Studio .NET project (along with all the files that come with it).
  As an example, let's say that I wanted to show you how to launch another application from the Microsoft® .NET Framework. In the Snippet Compiler I would start by creating a new file which creates a small console application. The snippet can be created inside the Main method of the console application, which is what I will do here. The following code snippet demonstrates how to create an instance of Notepad from the .NET Framework:
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName= "notepad.exe";
proc.Start();
proc.WaitForExit();
Of course this snippet would not compile by itself, but that is where Snippet Compiler comes into play. Figure 1 shows this code sample in Snippet Compiler.
Figure 1 Snippet Compiler
Figure 1  Snippet Compiler
  To test this snippet, just press the play button (green triangle), and it will run in debug mode. The snippet will generate a console application popup, and Notepad will appear. When you close Notepad, the console application will close as well.
  Personally, I have found Snippet Compiler to be invaluable when trying to create a small example for someone who has asked me for help, when normally I would have to create a project, make sure everything compiles, send them the code snippet, and then delete the project. Snippet Compiler makes this process much easier and much more pleasant.
  Snippet Compiler was written by Jeff Key and can be downloaded from http://www.sliver.com/dotnet/SnippetCompiler.

Regulator
  Regulator is the most recent addition to my top tools list. It is a full-featured tool that makes it easy to build and test regular expressions. There is a renewed interest in regular expressions because of the excellent support for them in the .NET Framework. Regular expressions are used to define patterns in strings based on characters, frequency, and character order. They are most commonly used as a means to validate user input or as a way to find a string of characters inside a larger string—for instance, when looking for a URL or e-mail address on a Web page.
  Regulator allows you to enter a regular expression and some input against which you would be running this expression. This way you can see how the regular expression will act and what kind of matches it will return before implementing it in your application. Figure 2 shows Regulator with a simple regular expression.
  The document contains the regular expression, in this example it is [0-9]* which should match any number of digits in a row. The box in the bottom-right contains the input for this regular expression, and the box on the bottom-left shows the matches that this regular expression finds in the input. The ability to write and test regular expressions in a separate application like this is much easier than trying to work with them in your app.
  One of the best features in Regulator is the ability to search the online regular expressions library at regexlib.com. For example, if you enter the string "phone" in the search box, you will find more than 20 different regular expressions that will match various phone numbers, including expressions for UK, Australian, and many other phone numbers.
  Regulator was written by Roy Osherove and can be downloaded at http://royo.is-a-geek.com/regulator.

CodeSmith
  CodeSmith is a template-based code-generation tool that uses a syntax similar to ASP.NET to generate any type of code or text. Unlike many other code-generation tools, CodeSmith does not require you to subscribe to a particular application design or architecture. Using CodeSmith, you can generate anything from a simple, strongly typed collection to an entire application.
  When you are building an application, you will often find yourself repeating certain tasks, whether it's writing data access code or building custom collections. CodeSmith is particularly useful at such times because you can write templates to automate those tasks and not only improve your productivity but also automate the tasks that are the most tedious to perform.
  CodeSmith ships with a number of templates, including ones for all the .NET collection types as well as ones to generate stored procedures, but the real power of this tool comes from being able to create custom templates. To get you started, I'll provide a quick introduction to building a custom template.

Building a Custom Template
  CodeSmith templates are simply text files which you can create in any text editor. Their only requirement is that they be saved with the .cst file extension. The sample template that I'm going to build will accept a string and then build a class based on that string. The first step to creating a template is to add the template header, which declares the language of the template, the target language, and a brief description of the template:
<%@ CodeTemplate Language="C#"    
   TargetLanguage="C#" 
   Description="Car Template" %>
<%@ CodeTemplate Language="C#"    
   TargetLanguage="C#" 
   Description="Car Template" %>

  The next part of the template is the property declarations, where you declare the properties that will be specified each time the template is run. With this template, the single property that I'm going to use is just a string, so the property declaration looks like this: 
<%@ Property Name="ClassName" Type="String" Category="Context" 
    Description="Class Name" %>

  This property declaration will make the ClassName property appear in the CodeSmith property window so that it can be specified when the template is run. The next step is to actually build the body of the template, which is very similar to coding with ASP.NET. You can see the body of the template in Figure 3. [Editor's Update - 6/16/2004: The code in Figure 3 has been updated to be safe for multithreaded operations.]
  As you can see, the template will take the string input and generate a singleton class using that class name. In the template body, the same opening and closing tags are used as in ASP.NET. In this template, I am simply inserting the property value, but you can also use any type of .NET code inside these tags. Once the template is complete, you load it into CodeSmith by either double-clicking or opening it from the CodeSmith application. Figure 4 shows this template loaded into CodeSmith.
  You can see that the property on the left is the one I declared in the template. If I enter "SingletonClass" as the class name and click the Generate button, the class shown in the bottom part of Figure 3 will be generated.
  CodeSmith is relatively easy to use and can produce some incredible results if applied correctly. One of the most common sections of an application that is targeted for code generation is the data access layer. CodeSmith includes a special assembly called the SchemaExplorer which can be used to generate templates from tables, stored procedures, or almost any other SQL Server™ object.
  CodeSmith was written by Eric J. Smith and is available for download at http://www.ericjsmith.net/codesmith.

NUnit
  NUnit is an open source unit testing framework built for the .NET Framework. NUnit allows you to write tests in the language of your choice to test a specific function of your application. Unit tests are an excellent way to test the functionality of your code when you first write it, and also to provide a method for regression testing of your application. The NUnit application provides a framework for writing unit tests, as well as a graphical interface to run these tests and view the results.

Writing an NUnit Test
  As an example, I'm going to test the functionality of the Hashtable class in the .NET Framework to determine if two objects can be added and then retrieved. My first step will be to add a reference to the NUnit.Framework assembly, which will give me access to the attributes and methods of the NUnit framework. Next I'll create a class and mark it with the TestFixture attribute. This attribute lets NUnit know that this class contains NUnit tests: 
using System;
using System.Collections;
using NUnit.Framework;

namespace NUnitExample
{
    [TestFixture]
    public class HashtableTest {
        public HashtableTest() {
            
        }
    }
}
  Next I'll create a method and mark it with the [Test] attribute so that NUnit knows that this method is a test. Then I'll set up a Hashtable and add two values to it, then use the Assert.AreEqual method to see if I can retrieve the same values that I added to the Hashtable, as shown in the following: 
[Test]
public void HashtableAddTest()
{
    Hashtable ht = new Hashtable();
            
    ht.Add("Key1", "Value1");
    ht.Add("Key2", "Value2");

    Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!");
    Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!");
}
  This will confirm that I can add and then retrieve values from the Hashtable—a simple test, but one that showcases the capabilities of NUnit. There are a number of test types, as well as various Assert methods, that can be used to test every part of your code.
  To run this test, I'll need to build the project, open the generated assembly in the NUnit application, and then click the Run button. Figure 5 shows the results. I get a warm and fuzzy feeling when I see that big green bar because it lets me know that the test passed. This simple example shows how easy and powerful NUnit and unit testing can be. Being able to write a unit test that can be saved and rerun whenever you change code not only makes it easier for you to detect defects in your code, but the result is that you can deliver better applications.
Figure 5 NUnit
Figure 5  NUnit
  NUnit is an open-source project that is available for download from http://www.nunit.org. There is also an excellent NUnit Visual Studio .NET add-in which allows you to run unit tests directly from Visual Studio. This can be found at http://sourceforge.net/projects/nunitaddin. For more information on NUnit and its place in test-driven development, see the article " Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques" in the April 2004 issue of MSDN® Magazine.

FxCop
  The .NET Framework is very powerful, which means there is great potential to create excellent applications, but there is equal opportunity to create poor programs. FxCop is one of the tools that can be used to help create better applications by enabling you to examine an assembly and check it for compliance using a number of different rules. FxCop comes with a set number of rules created by Microsoft, but you can also create and include your own rules. For instance, if you decided that all classes should have a default constructor that takes no arguments, you could write a rule that checks for a constructor on each class of an assembly. This way, no matter who writes the code, you will have a certain level of consistency. If you want more information on creating custom rules, see John Robbins' Bugslayer column on the subject in the June 2004 issue of MSDN Magazine.
  So let's take a look at FxCop in action and see what it finds wrong with the NUnitExample assembly that I have been working with. When you open FxCop you first need to create an FxCop project and then add to it the assembly that you want to test. Once the assembly is added to the project, you can press Analyze, and FxCop will examine the assembly. The errors and warning found in this assembly are shown in Figure 6.
  FxCop found a couple of problems with my assembly. You can double-click on an error to see the details, including a description of the rule and where you can find more information. (Something you can do for fun is run FxCop on the Framework assemblies and see what turns up.)
  FxCop can help you create better, more consistent code, but it cannot make up for poor application design or just plain poor programming. FxCop is also not a replacement for peer code review, but because it can catch a lot of errors before code review, more time can be spent on serious issues rather than having to worry about naming conventions.
  FxCop was developed by Microsoft and is available for download from http://www.gotdotnet.com/team/fxcop.

Lutz Roeder's .NET Reflector
  The next essential tool is called .NET Reflector, which is a class browser and decompiler that can examine an assembly and show you just about all of its secrets. The .NET Framework introduced the world to the concept of reflection which can be used to examine any .NET-based code, whether it is a single class or an entire assembly. Reflection can also be used to retrieve information about the various classes, methods, and properties included in a particular assembly. Using .NET Reflector, you can browse the classes and methods of an assembly, you can examine the Microsoft intermediate language (MSIL) generated by these classes and methods, and you can decompile the classes and methods and see the equivalent in C# or Visual Basic® .NET.
  To demonstrate the workings of .NET Reflector, I am going to load and examine the NUnitExample assembly already shown. Figure 7 shows this assembly loaded in .NET Reflector.
Figure 7 NUnitExample Assembly
Figure 7  NUnitExample Assembly
  Inside of .NET Reflector there are various tools that you can use to examine this assembly further. To view the MSIL that makes up a method, click on the method and select Disassembler from the menu.
  In addition to being able to view the MSIL, you can also view the method as C# by selecting Decompiler under the Tools menu. You could also view this method decompiled to Visual Basic .NET or Delphi by changing your selection under the Languages menu. Here is the code that .NET Reflector generated:
public void HashtableAddTest()
{ 
    Hashtable hashtable1;
    hashtable1 = new Hashtable();
    hashtable1.Add("Key1", "Value1");
    hashtable1.Add("Key2", "Value2");
    Assert.AreEqual("Value1", hashtable1["Key1"], 
       "Wrong object returned!");
    Assert.AreEqual("Value2", hashtable1["Key2"],
       "Wrong object returned!");
}
The previous code looks very much like the code I actually wrote for this method. Here is the actual code from this assembly:
public void HashtableAddTest()
{
    Hashtable ht = new Hashtable();
            
    ht.Add("Key1", "Value1");
    ht.Add("Key2", "Value2");

    Assert.AreEqual("Value1", ht["Key1"],
        "Wrong object returned!");
    Assert.AreEqual("Value2", ht["Key2"],
        "Wrong object returned!");
}
Although there are some minor differences with the code, they are functionally identical.
  While this example was a good way to show actual code versus decompiled code, it does not represent what I consider to be the best use of .NET Reflector, which is to examine .NET Framework assemblies and methods. The .NET Framework offers many different ways to perform similar operations. For example, if you need to read a set of data from XML, there are a variety of different ways to do this using XmlDocument, XPathNavigator, or XmlReader. By using .NET Reflector, you can see what Microsoft used when writing the ReadXml method of the DataSet, or what they did when reading data from the configuration files. .NET Reflector is also an excellent way to see the best practices for creating objects like HttpHandlers or configuration handlers because you get to see how the team at Microsoft actually built those objects in the Framework.
  .NET Reflector was written by Lutz Roeder and can be downloaded from http://www.aisto.com/roeder/dotnet.

NDoc
  Code documentation is almost always a dreaded task. I am not talking about the early design documents, or even the more detailed design documents; I am talking about documenting individual methods and properties on classes. The NDoc tool will automatically generate documentation for your code using reflection to examine the assembly and using the XML generated from your C# XML comments. XML comments are only available for C#, but there is a Visual Studio .NET Power Toy called VBCommenter which will do something similar for Visual Basic .NET. In addition, the next release of Visual Studio will support XML comments for more languages.
  With NDoc you are technically still documenting your code, but you are documenting as you write it (in the XML comments), which is much easier to swallow. The first step when using NDoc is to turn on XML comments generation for your assembly. Right-click the project and select Properties | Configuration Properties | Build, then enter a path in which to save the XML file in the XML Documentation File option. When the project is built, an XML file will be created with all of the XML comments included. Here is a look at a method from the NUnit example documented with XML:
/// <summary>
/// This test adds a number of values to the Hashtable collection 
/// and then retrieves those values and checks if they match.
/// </summary>
[Test]
public void HashtableAddTest()
{
    //Method Body Here
}

  The XML documentation on this method will be extracted and saved in the XML file, shown here:
<member name="M:NUnitExample.HashtableTest.HashtableAddTest">
  <summary>This test adds a number of values to the Hashtable collection
    and then retrieves those values and checks if they match.</summary> 
</member>
NDoc uses reflection to look at your assembly, then reads the XML in this document, and matches them up. NDoc uses this data to create any number of different documentation formats, including HTML help files (CHMs). After generating the XML file, the next step is to load the assembly and the XML file into NDoc so they can be processed. This is done simply by opening NDoc and clicking the Add button.
  Once the assembly and XML file are loaded into NDoc and after you customize the output using the range of properties available, clicking on the Generate button will start the process of generating the documentation. Using the default properties, NDoc generates some very attractive and functional .html and .chm files, thereby automating in a quick and efficient manner what would otherwise be a tedious task.
  NDoc is an open source project and can be downloaded from http://ndoc.sourceforge.net.

NAnt
  NAnt is a .NET-based build tool that, unlike the current version of Visual Studio .NET, makes it easy to create a build process for your project. When you have a large number of developers working on a single project, you can't rely on the build from a single user's box. You also do not want to have to build the project manually on a regular basis. Instead, you create an automated build process that runs every night. NAnt allows you to build your solution, copy files, run NUnit tests, send e-mail, and much more. Unfortunately, NAnt is lacking a nice looking graphical interface, but it does have a console application and XML files that specify which tasks should be completed during the build process. Note that MSBuild, the new build platform that's part of Visual Studio 2005, provides for very robust build scenarios and is similarly driven by XML-based project files.

NAnt in Action
  In this example I am going to create an NAnt build file for the NUnitExample solution that I created earlier. First I need to create an XML file with the .build extension, place it in the root of my project, and then add an XML declaration to the top of the file. The first tag I need to add to the file is the project tag:
<?xml version="1.0"?>
<project name="NUnit Example" default="build" basedir=".">
    <description>The NUnit Example Project</description>
</project>
The project tag is also used to set the name of the project, the default target, and the base directory. The description tag is used to set a brief description of this project.
  Next, I'll add the property tag, which can be used to store a setting in a single location that can then be accessed from anywhere in the file. In this case, I am going to create a property called debug, which I can then set to true or false, reflecting whether or not I want the project to be compiled in the debug configuration. (In the end, this particular property does not actually affect how the project will be built; it is simply a variable that you set and which will be read from later when you are actually determining how to build the project.)
  Next, I need to create a target tag. A project can contain multiple targets which can be specified when NAnt is run. If no target is specified, the default is used, which I set in the project element. In this example, the default target is build. Let's take a look at the target element, which will contain the majority of the build info:
<target name="build" description="compiles the source code">
</target>
Inside the target element, I am going to set the name of the target to build and create a description of what this target will do. I'll also create a csc element, which is used to specify what should be passed to the csc C# compiler. Let's take a look at the csc element: 
<csc target="library" output="./bin/debug/NUnitExample.dll" 
    debug="${debug}">
<references>
    <includes name="C:/program files/NUnit V2.1/bin/NUnit.Framework.dll"/>
</references>
    <sources>
       <includes name="HashtableTest.cs"/>
    </sources>
</csc>

  First, I have to set the target of the csc element. In this case I will be creating a .dll file so I set the target to library. Next, I have to set the output of the csc element, which is where the .dll file will be created. Finally, I need to set the debug property, which determines whether the project will be compiled in debug. Since I created a property earlier to store this value, I can use the following string to access the value of that property: ${debug}. The csc element also contains a number of sub-elements. I need to create two elements: the references element will tell NAnt which assemblies I need to reference for this project, and the sources element will tell NAnt which files to include in the build. In this example, I reference the NUnit.Framework.dll assembly and include the HashtableTest.cs file. The complete build file is shown in Figure 8. (You would normally also create a clean target that would be used to delete the generated files, but I have omitted it for the sake of brevity.)
  To build this file I need to go to the root directory of my project, where the build file is located, and execute nant.exe from that location. If the build is successful, you can find the .dll and .pdb file in the bin directory of this application. While using NAnt is definitely not as easy as clicking Build in Visual Studio, it is a very powerful tool for developing a build process that runs on an automated schedule. NAnt also includes helpful features such as the ability to run unit tests or copy additional files (features that are not supported by the current Visual Studio build process).
  NAnt is an open source project and can be downloaded from http://nant.sourceforge.net.

Switch Tools
  I have lumped together two separate tools under the heading Switch Tools. These two tools are rather simple, but can be extremely useful. The first is the ASP.NET Version Switcher, which can be used to switch the version of ASP.NET that a virtual directory is running under. The second tool is the Visual Studio Converter, which can be used to switch a project file from Visual Studio .NET 2002 to Visual Studio .NET 2003.
  When IIS handles a request, it looks at the extension of the file that is being requested, and then based on the extension mappings for that Web site or virtual directory, it either delegates the request to an ISAPI extension or handles it itself. This is how ASP.NET works; extension mappings are registered for all of the ASP.NET extensions and directs them to the aspnet_isapi.dll. This works flawlessly until you install ASP.NET 1.1, which upgrades the extension mapping to the new version of aspnet_isapi.dll. This causes errors when an application built on ASP.NET 1.0 tries to run with version 1.1. To fix this, you can switch all of the extension mappings back to the 1.0 version of aspnet_isapi.dll, but with 18 extension mappings it is not a lot of fun to do this by hand. This is where the ASP.NET Version Switcher becomes useful. This small utility can be used to switch the version of the .NET Framework that any single ASP.NET application is using.
Figure 9 ASP.NET Version Switcher
Figure 9  ASP.NET Version Switcher
   Figure 9 shows the ASP.NET Version Switcher in action. Using it is as simple as selecting the application and then selecting the version of the .NET Framework that you would like the application to use. The tool then uses the aspnet_regiis.exe command-line tool to switch the application to the selected version of the Framework. This tool will become even more useful as future versions of ASP.NET and the .NET Framework are released.
  ASP.NET Version Switcher was written by Denis Bauer and is available for download from http://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx.
  The Visual Studio .NET Project Converter (see Figure 10) is very similar to the ASP.NET Version Switcher, except that it is used to switch the version of a Visual Studio project file. Even though there is only a small difference between versions 1.0 and 1.1 of the .NET Framework, once a project file from Visual Studio .NET 2002 is converted to Visual Studio .NET 2003, it cannot be converted back. While this might not be an issue most of the time (since there are few breaking changes between the .NET Framework versions 1.0 and 1.1), at some point you may need to switch a project back. This converter can convert any solution or project file from Visual Studio 7.1 (Visual Studio .NET 2003) to Visual Studio 7.0 (Visual Studio .NET 2002), and back if necessary.
Figure 10 Visual Studio .NET Project Converter
Figure 10  Visual Studio .NET Project Converter
  The Visual Studio .NET Project Converter was written by Dacris Software. It is available for download from http://www.codeproject.com/macro/vsconvert.asp.

Conclusion
  This has been a bit of a whirlwind tour of these tools, but I have tried to present you with at least enough information to whet your appetite. I trust that this article has provided you with some insight into a couple of free tools that you can start using right away to write better projects. I also urge you to make sure you have all the other right tools available to you, whether it is newest version of Visual Studio, a powerful computer, or a free utility. Having the right tools can make all the difference.


James Avery  is a consultant working with .NET and other Microsoft technologies. He has written a number of books and articles, his most recent book being ASP.NET Setup and Configuration Pocket Reference (Microsoft Press, 2003). You can e-mail him at javery@infozerk.com and read his weblog at http://www.dotavery.com/blog.


From the July 2004 issue of MSDN Magazine.
Get it at your local newsstand, or better yet, subscribe.

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值