新的项目要求使用C#,对于习惯了Java开发模式和环境的朋友来说,一开始总会有些不适应。
拿我自己的体验来说,VS2005跟Eclipse SDK相比,当然画GUI和调试的直观性方面给我留下的印象很深,不过也有些我认为缺少了的东西:增量编译(很多时候只有F6以后,编译错误提示才会消失,有些引用和IntelliSense才生效,不像Eclipse,保存后自动增量编译)、代码排版(很怀念Ctrl-Shift-F)、引用整理(很怀念Ctrl-Shift-O)、很多有用的重构(可以说VS里面代码级的重构相比很多Java IDE差远了)、单元测试的集成(NUnit理论上应该可以很好的集成到VS2005,不过还是花了我一些功夫)、CVS客户端(很怀念Eclipse SDK)。当然,一些IDE当中相对小的差异一开始也很难适应,不过这些也可以理解,属于正常范畴。
最近为了把项目的一些基调和开发模式定下来,做了一些尝试,我想也许对大家还有些用,整理一下放在这里。
一个好的.NET项目,我相信有些东西事先定义好,对项目整个过程是有很大好处的,这些东西至少应该包括:开发工具选择和配置、代码模板、单元测试、代码自动化review工具、自动编译和测试、缺陷跟踪、文档管理等。当然如果不计成本,那么有很多重量级的SDLC框架可以用,如VSTS(MSF)、Rational(RUP)和Borland的集成工具,以上这些环节的问题相应的框架也大都给出了很好的解决方案,但是毕竟不是所有的项目都会购买和采用那么"重"的方法和过程,很多时候就算有那个预算,对于特定的项目,实施起来也不见得就会收到好的效果。于是我们接触到的很多项目,其实都还是需要自己去寻找适合的工具来把整个周期串起来。以下是我在尝试找到一套合适方案时遇到的一些特定问题以及解决办法:
首先是单元测试工具以及和IDE的集成。在Eclipse SDK中,我们不必太过关心这个问题,因为Eclipse已经很好的集成了JUnit。但是在.NET的世界,人们是怎么做的呢?答案是NUnit,一个跟JUnit非常类似的东西。和JUnit一样,NUnit也提供了命令行版本和GUI版本,但是VS里面并没有直接提供集成,你更多的时候需要从外部运行NUnit,当然这样很不爽啦。VS号称是自己也提供了单元测试工具,但是那仅仅在高端VSTS中才有。如何解决这个集成的问题呢?可以到http://www.testdriven.net/ 上下载一个TestDriven.NET的VS add-in。安装以后,就可以在VS中调用我们可能经常需要调用的NUnit来跑自己的单元测试了。
其次是代码模板。一个项目,不管大小,总会涉及到相当数量的源代码文件,我们希望这些源代码都包括一些共有的东西和特定的注释,怎么办?在Eclipse里面有code template的概念,那么在VS里呢?答案是Project Template和Item Template。一开始我根本摸不着头脑,只看到MSDN上正在说Code Snippet,于是我实现的1.0版代码模板就是基于Code Snippet的,用起来很不方便,有关Code Snippet,我等下还会提到,这里先看Templates。我Google了一下相关的Project Template和Item Template的说明,基本都是VS 2003的,不过它们给了我很好的提示,至少可以知道VS在生成默认的代码时是怎样一个思路。所有的VS 2005代码模板都可以在%VS_2005_INSTALL_PATH%\Common7\IDE\ProjectTemplates和%VS_2005_INSTALL_PATH%\Common7\IDE\ItemTemplates目录下面找到,Project Template和Item Template不同的是Project Templates是在你新建一个项目时使用的模板,而Item Templates是在你往一个现有项目中添加item,如Form、Class等的时候使用。这里需要注意两点:一是VS 2005跟VS 2003不同,templates不再是直接的.cs文件等,而是打包在了.zip中,需要修改的话,需要把新的文件重新压到.zip中;二是除了template目录,还有一个TemplateCache目录,为了立即看到模板的效果,这里面的相应.cs文件等也需要修改。模板改起来相当直接,一看便知,比如新建Form的模板:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace $rootnamespace$
{
public partial class $safeitemrootname$: Form
{
public $safeitemrootname$()
{
InitializeComponent();
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace $rootnamespace$
{
public partial class $safeitemrootname$: Form
{
public $safeitemrootname$()
{
InitializeComponent();
}
}
}
接下来说说Code Snippet,这个东东被MSDN吹得有点大,不过用起来实在有些不顺手,你虽然可以定义一大块代码片断,然后填一些参数,就能得到一个定制的代码段,但是毕竟你还是需要自己写很多东西,然后使用的话需要在代码编辑器里面点很多下才出来,又没有很好的快捷方式。不客气地说我觉得用Code Snippet来模拟Eclipse的很多现成的重构功能实在不能够体现出优势。退一万步讲,有总比没有强,至少你还是可以做一些东西的。使用现成的Code Snippet很简单,只要把VS指向你存放Code Snippets的目录即可,新的Code Snippets会被自动扫描到。方法是:Tools -> Code Snippets Manager或者Ctrl-K Ctrl-B然后添加目录名。所有的Code Snippets文件都以.snippet后缀结尾,其实内部是个XML,像这个样子:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Insert a simple set of getter and setter pair</Title>
<Author>Sean GAO</Author>
<Description></Description>
<Shortcut>simplisticGetterSetter</Shortcut>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>AccessLevel</ID>
<ToolTip></ToolTip>
<Default>public</Default>
</Literal>
<Literal>
<ID>PropertyType</ID>
<ToolTip></ToolTip>
<Default>string</Default>
</Literal>
<Literal>
<ID>PropertyName</ID>
<ToolTip></ToolTip>
<Default>name</Default>
</Literal>
<Literal>
<ID>LocalVarName</ID>
<ToolTip></ToolTip>
<Default>localVar</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[ $AccessLevel$ $PropertyType$ $PropertyName$
{
get { return $LocalVarName$; }
set { $LocalVarName$ = value; }
}
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Insert a simple set of getter and setter pair</Title>
<Author>Sean GAO</Author>
<Description></Description>
<Shortcut>simplisticGetterSetter</Shortcut>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>AccessLevel</ID>
<ToolTip></ToolTip>
<Default>public</Default>
</Literal>
<Literal>
<ID>PropertyType</ID>
<ToolTip></ToolTip>
<Default>string</Default>
</Literal>
<Literal>
<ID>PropertyName</ID>
<ToolTip></ToolTip>
<Default>name</Default>
</Literal>
<Literal>
<ID>LocalVarName</ID>
<ToolTip></ToolTip>
<Default>localVar</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[ $AccessLevel$ $PropertyType$ $PropertyName$
{
get { return $LocalVarName$; }
set { $LocalVarName$ = value; }
}
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
我们可以看到,首先在.snippet中我定义了一些变量,然后在<Code/>段加入了<![CDATA[...]]>,就这么简单。
最后,还剩一些具体的工具,选择面比较广,我只列举一下我都选了哪些:
- 代码review和分析工具:FxCop,可以在GotDotNet网站上下载:http://www.gotdotnet.com/team/fxcop/ 。
- 自动编译管理:NANT和CruiseControl.NET:http://nant.sourceforge.net/ 和 http://ccnet.thoughtworks.com/ 。
- 缺陷跟踪:mantis:http://www.mantisbt.org/ 。
- 文档管理: jLibrary:http://jlibrary.sourceforge.net/ 。
- 版本控制:CVSNT和Eclipse SDK:http://www.cvsnt.org/ 和 http://eclipse.org/ 。
暂时就是这么多,如果你和我一样从Java转向.NET,然后正在犯愁如何做一个.NET项目的前期准备,希望能给你一些参考。
大胃 2006-04-01 17:04
文章来源:http://www.blogjava.net/sean/archive/2006/04/01/38624.html