【已发表于《程序员》2007年第1期,全名《程序员的私人外包专家——探索CodeSmith代码生成器》,因篇幅限制,杂志上略有删减】
引言
如果机器猫是个软件开发人员,那么它一定能从口袋里掏出如图1所示的软件,简洁明快的界面上仅有几个必要的输入控件,只要用鼠标轻轻点击这个按钮,硬盘便会像着了魔一样疯狂地发出一阵吱吱的叫声,数分钟后,当这个世界重新安静下来时,一款全新的软件诞生了!
图1,传说中机器猫的软件开发解决方案
不过就目前的技术水平来说,这还只能算是“痴人说梦”。那么,有没有什么软件可以减轻程序员的重复性劳动,将“百忙”变为“不忙”,使得大家有更多的时间来陪伴家人和女友呢?现在软件行业不是流行“外包”吗?大公司外包给小公司、小公司外包给个体户,那么程序员可以将手头上一部分编码工作外包给谁呢?除了Ctrl+C、Ctrl+V这对著名的孪生兄弟外,我想CodeSmith会是一个更好的选择。
What
什么是CodeSmith?从字面上直译可以看作“代码工匠”。这倒是个很拟人化的名称,顾名思义,CodeSmith的目标就是根据模板生成规范可用的代码,为程序员减轻工作负担。
程序员是软件开发团队中的最小单位,有什么任务都只能自己一肩扛起而无法再往下分配。但是程序员又是聪明的,他们总是能找到很多美妙的办法来减轻压力,代码生成器就是一个典型的例子。事实上,Visual Studio 2005本身就自带了代码生成的功能,比如您在代码编辑器中输入关键字“for”,然后直接按Tab键,代码生成器便会为您生成好一段模板式的代码:
图2,Visual Studio 2005的代码生成功能
Visual Studio 2005还能自动生成其它更多形式的代码,但终究不如CodeSmith那样强大和丰富,毕竟术业有专攻嘛。CodeSmith是以模板作基础来为程序员生成高质量代码的,模板可大可小,CodeSmith一次能够生成的代码量也就可多可少,这主要靠具体问题具体分析。
CodeSmith的模板是以“.cst”为后缀名的代码文件,其风格非常类似于ASP.NET。模板中除了大量固定的代码以外,还有遍布于各处的元数据(metadata)。固定代码就是会被CodeSmith原封不动地输出的代码,而元数据则可以被看作是模板中的变量。那么现在我们就通过一个简单的模板文件来了解CodeSmith的工作原理:
如果您了解ASP.NET的语法,那么就很好理解CodeSmith模板文件了。第一条语句:
● Description:作为模板的描述性信息并可以在该模板的ToolTip中显示;
● Inherits:尽管默认情况下所有模板都继承自CodeSmith.Engine.CodeTemplate,但仍然可以由您来指定模板继承自其它类(只要该类直接或间接地继承自CodeSmith.Engine.CodeTemplate);
● Src:该属性使您能够将其它类的功能添加进当前模板,您能够用这个属性来实现“代码隐藏”模型;
● Debug:当该属性被设置为True时,您就可以使用System.Diagnostics.Debugger.Break方法来为您的模板设置断点;
● OutputType:该属性用于指定以“Normal”、“Trace”或“None”方式输出模板;
● LinePragmas:当该属性被设置为True时,模板错误将指向源代码;设置为False时,模板错误将指向编译后的代码;
● ResponseEncoding:用于设置模板及输出的编码,该属性支持来自于System.Text.Encoding.GetEncoding方法的值,默认情况下为ASCII。
模板中的代码可以分为三个部分:静态、系统生成和动态的。静态代码就是系统将原封不动地输出的代码,例如前面代码示例中的:
CodeSmith可以自动生成部分代码,例如示例中的:
CodeSmith将<%= %>标记中间的部分作为计算表达式,在运行时计算该表达式并将结果输出到代码中相应的位置。CodeSmith中的属性用以实现用户自定义的输出内容,例如示例中的:
属性具有名称和类型,这是必需的内容,另外还可以给属性设置一个默认值,添加一些描述性说明以便于用户在使用该属性时能够迅速地了解其用途和用法。使用属性时仍然会用到<%= %>标签,在该标签中插入需要的属性名即可,例如:
尽管模板文件的内容似乎要比所需要的源代码复杂得多,但这是一劳久逸的工作,因为您可以用模板生成无数代码,当初编辑模板时花费在编写动态内容及属性上的辛苦付出将在日后使用模板时得到丰厚的汇报!
当前最新版本是于11月8号发布的V4.0。作为一次大的版本升级,CodeSmith理所当然地给我们带来了新的特性,这些新特性一方面使CodeSmith成为更加强大的软件,另一方面也使得程序员们更加青睐这位得力助手。目前CodeSmith V4.0已经很好地集成进Visual Studio 2005,这样一来,程序员就能够更加方便地使用它了。那么,就让我们来看看,CodeSmith还为我们带来了哪些振奋人心的新特性吧:
● CodeSmith Project:CSP的出现使得您无论在Visual Studio 2005、MSBuild、Windows Explorer、命令行、批处理文件或是CodeSmith自身环境下都可以以轻松、一致的方式自动地生成代码;
● ActiveSnippets:比Visual Studio 2005的Snippet更加强大,可以通过执行逻辑处理或是访问复杂的原数据来控制代码片段的输出;
● CodeSmith Maps:创建字典式的映射,例如SQL与C#的数据类型映射;
● .netTiers 2.0:增强的.netTiers模板;
● Extended Property Management:可以在CodeSmith Studio中编辑或者添加模式扩展属性;
● Property Persistence:现在CodeSmith可以记住您最近一次执行模板时的属性值;
● CodeSmith Studio:改进了智能感应并全面提升性能;
How
怎样使用CodeSmith?不论我说的多么天花乱坠,如果不告诉大家一些基本常用的使用方式,那么本文就起不到广而告之的作用。那么我就以简单的例子来向大家演示如何使用CodeSmith来减轻开发人员的工作负担。
您可以从CodeSmith Tool LLC的官方网站上下载该软件,推荐使用Professional版,安装完毕之后您会看到有两个图标,一个是CodeSmith Explorer,另一个是CodeSmith Studio,前者是利用模板输出代码的,而后者则用于编辑模板。我们先运行CodeSmith Explorer来看看如何通过模板得到我们想要的代码。
图3,CodeSmith Explorer界面
运行CodeSmith Explorer就能看到如图3所示的界面,点击Collections前面的加号就会看到有个ArrayList.cst的节点,如图4所示:
图4,选中ArrayList.cst模板
双击该节点,便会弹出CodeSmith的输出窗口,在窗口的左边是属性输入框,您可以根据自己的需要设定各属性的值,然后只需轻轻点击下面的Generate按钮,CodeSmith就能立刻为您献上一份长长的源代码,如图5所示:
图5,使用CodeSmith生成源代码
该例子所生成的源代码共有2302行,想想如果手工输入这么多代码需要花费多少时间呢?而使用CodeSmith则仅花费了不到1分钟时间,其魅力则就不言而喻了!
如果您对CodeSmith提供的模板感到不太满意,或者您需要根据自己的需求来制作相应的模板,则可以使用CodeSmith Studio来新建或编辑现有代码模板,例如,你对刚才我们使用到的ArrayList.cst模板感到不甚满意,觉得自己有更好的创意,那么你可以运行CodeSmith Studio,然后在右边的文件列表中找到并打开ArrayList.cst,还记得刚才我介绍的那些模板元素以及它们各自的特性和用途吗?好吧,现在就开始动手根据您自己的想法来完善这个模板吧。
图6,编辑代码模板
在这里因为篇幅有限,所以我只是使用了一个最简单的例子来向大家展示使用CodeSmith的好处,其实CodeSmith的强大远不仅仅是输出这样简单的代码文件,记住,CodeSmith是基于模板生成代码的,因此,套用那句“人有多大胆,地有多高产”的话来说就是:“模板有多强大,代码就有多丰富!”
Why
为什么向您推荐CodeSmith?可千万别把我当成了托儿,我可没有收取CodeSmith Tools LLC任何物质上以及精神上的报酬,不过是为了和广大开发着朋友们分享一款优秀的专业软件而已。
其实有很多代码都是不需要我们自己从头到尾亲自写一遍的,尤其是在工作中,为什么不能用更少的时间完成更多的事情呢?程序员从事的是脑力劳动,我们应该充分运用我们的头脑来找到解决问题的更快更好的办法,只有当我们能够很好地解决自己工作中的问题的时候,我们才能够为我们的用户提供能很好解决他们面临的问题的解决方案。
引言
如果机器猫是个软件开发人员,那么它一定能从口袋里掏出如图1所示的软件,简洁明快的界面上仅有几个必要的输入控件,只要用鼠标轻轻点击这个按钮,硬盘便会像着了魔一样疯狂地发出一阵吱吱的叫声,数分钟后,当这个世界重新安静下来时,一款全新的软件诞生了!
图1,传说中机器猫的软件开发解决方案
不过就目前的技术水平来说,这还只能算是“痴人说梦”。那么,有没有什么软件可以减轻程序员的重复性劳动,将“百忙”变为“不忙”,使得大家有更多的时间来陪伴家人和女友呢?现在软件行业不是流行“外包”吗?大公司外包给小公司、小公司外包给个体户,那么程序员可以将手头上一部分编码工作外包给谁呢?除了Ctrl+C、Ctrl+V这对著名的孪生兄弟外,我想CodeSmith会是一个更好的选择。
What
什么是CodeSmith?从字面上直译可以看作“代码工匠”。这倒是个很拟人化的名称,顾名思义,CodeSmith的目标就是根据模板生成规范可用的代码,为程序员减轻工作负担。
程序员是软件开发团队中的最小单位,有什么任务都只能自己一肩扛起而无法再往下分配。但是程序员又是聪明的,他们总是能找到很多美妙的办法来减轻压力,代码生成器就是一个典型的例子。事实上,Visual Studio 2005本身就自带了代码生成的功能,比如您在代码编辑器中输入关键字“for”,然后直接按Tab键,代码生成器便会为您生成好一段模板式的代码:
图2,Visual Studio 2005的代码生成功能
Visual Studio 2005还能自动生成其它更多形式的代码,但终究不如CodeSmith那样强大和丰富,毕竟术业有专攻嘛。CodeSmith是以模板作基础来为程序员生成高质量代码的,模板可大可小,CodeSmith一次能够生成的代码量也就可多可少,这主要靠具体问题具体分析。
CodeSmith的模板是以“.cst”为后缀名的代码文件,其风格非常类似于ASP.NET。模板中除了大量固定的代码以外,还有遍布于各处的元数据(metadata)。固定代码就是会被CodeSmith原封不动地输出的代码,而元数据则可以被看作是模板中的变量。那么现在我们就通过一个简单的模板文件来了解CodeSmith的工作原理:
1 <% @ Template Language = " C# " TargetLanguage = " C# " Description = " Demonstrates the most basic template. " %>
2 <% @ Property Name = " SampleBooleanProperty " Type = " System.Boolean " Default = " True " Category = " Options " Description = " This is a sample boolean property. " %>
3 <% @ Property Name = " SampleStringProperty " Type = " System.String " Default = " SampleString " Category = " Options " Description = " This is a sample string property. " %>
4 // This class generated by CodeSmith on <%= DateTime.Now.ToLongDateString() %>
5 public class SimpleTemplate
6 {
7 public SimpleTemplate() : base()
8 {
9 }
10 <% if (SampleBooleanProperty) { %>
11
12 private void <%= SampleStringProperty %>()
13 {
14 // Do something
15 }
16 <% } %>
17}
2 <% @ Property Name = " SampleBooleanProperty " Type = " System.Boolean " Default = " True " Category = " Options " Description = " This is a sample boolean property. " %>
3 <% @ Property Name = " SampleStringProperty " Type = " System.String " Default = " SampleString " Category = " Options " Description = " This is a sample string property. " %>
4 // This class generated by CodeSmith on <%= DateTime.Now.ToLongDateString() %>
5 public class SimpleTemplate
6 {
7 public SimpleTemplate() : base()
8 {
9 }
10 <% if (SampleBooleanProperty) { %>
11
12 private void <%= SampleStringProperty %>()
13 {
14 // Do something
15 }
16 <% } %>
17}
如果您了解ASP.NET的语法,那么就很好理解CodeSmith模板文件了。第一条语句:
<% @ Template Language = " C# " TargetLanguage = " C# " Description = " Demonstrates the most basic template. " %>
是模板文件的声明语句,每个模板文件都必须以此作为开头,它包含了必要的声明信息,如模板语言、目标语言以及模板描述。除必需的“Language”属性以外,CodeSmith还提供7个可供模板声明使用的属性:● Description:作为模板的描述性信息并可以在该模板的ToolTip中显示;
● Inherits:尽管默认情况下所有模板都继承自CodeSmith.Engine.CodeTemplate,但仍然可以由您来指定模板继承自其它类(只要该类直接或间接地继承自CodeSmith.Engine.CodeTemplate);
● Src:该属性使您能够将其它类的功能添加进当前模板,您能够用这个属性来实现“代码隐藏”模型;
● Debug:当该属性被设置为True时,您就可以使用System.Diagnostics.Debugger.Break方法来为您的模板设置断点;
● OutputType:该属性用于指定以“Normal”、“Trace”或“None”方式输出模板;
● LinePragmas:当该属性被设置为True时,模板错误将指向源代码;设置为False时,模板错误将指向编译后的代码;
● ResponseEncoding:用于设置模板及输出的编码,该属性支持来自于System.Text.Encoding.GetEncoding方法的值,默认情况下为ASCII。
模板中的代码可以分为三个部分:静态、系统生成和动态的。静态代码就是系统将原封不动地输出的代码,例如前面代码示例中的:
public SimpleTemplate() : base ()
CodeSmith可以自动生成部分代码,例如示例中的:
// This class generated by CodeSmith on <%= DateTime.Now.ToLongDateString() %>
CodeSmith将<%= %>标记中间的部分作为计算表达式,在运行时计算该表达式并将结果输出到代码中相应的位置。CodeSmith中的属性用以实现用户自定义的输出内容,例如示例中的:
<% @ Property Name = " SampleStringProperty " Type = " System.String " Default = " SampleString " Category = " Options " Description = " This is a sample string property. " %>
属性具有名称和类型,这是必需的内容,另外还可以给属性设置一个默认值,添加一些描述性说明以便于用户在使用该属性时能够迅速地了解其用途和用法。使用属性时仍然会用到<%= %>标签,在该标签中插入需要的属性名即可,例如:
private void <%= SampleStringProperty %> ()
尽管模板文件的内容似乎要比所需要的源代码复杂得多,但这是一劳久逸的工作,因为您可以用模板生成无数代码,当初编辑模板时花费在编写动态内容及属性上的辛苦付出将在日后使用模板时得到丰厚的汇报!
当前最新版本是于11月8号发布的V4.0。作为一次大的版本升级,CodeSmith理所当然地给我们带来了新的特性,这些新特性一方面使CodeSmith成为更加强大的软件,另一方面也使得程序员们更加青睐这位得力助手。目前CodeSmith V4.0已经很好地集成进Visual Studio 2005,这样一来,程序员就能够更加方便地使用它了。那么,就让我们来看看,CodeSmith还为我们带来了哪些振奋人心的新特性吧:
● CodeSmith Project:CSP的出现使得您无论在Visual Studio 2005、MSBuild、Windows Explorer、命令行、批处理文件或是CodeSmith自身环境下都可以以轻松、一致的方式自动地生成代码;
● ActiveSnippets:比Visual Studio 2005的Snippet更加强大,可以通过执行逻辑处理或是访问复杂的原数据来控制代码片段的输出;
● CodeSmith Maps:创建字典式的映射,例如SQL与C#的数据类型映射;
● .netTiers 2.0:增强的.netTiers模板;
● Extended Property Management:可以在CodeSmith Studio中编辑或者添加模式扩展属性;
● Property Persistence:现在CodeSmith可以记住您最近一次执行模板时的属性值;
● CodeSmith Studio:改进了智能感应并全面提升性能;
How
怎样使用CodeSmith?不论我说的多么天花乱坠,如果不告诉大家一些基本常用的使用方式,那么本文就起不到广而告之的作用。那么我就以简单的例子来向大家演示如何使用CodeSmith来减轻开发人员的工作负担。
您可以从CodeSmith Tool LLC的官方网站上下载该软件,推荐使用Professional版,安装完毕之后您会看到有两个图标,一个是CodeSmith Explorer,另一个是CodeSmith Studio,前者是利用模板输出代码的,而后者则用于编辑模板。我们先运行CodeSmith Explorer来看看如何通过模板得到我们想要的代码。
图3,CodeSmith Explorer界面
运行CodeSmith Explorer就能看到如图3所示的界面,点击Collections前面的加号就会看到有个ArrayList.cst的节点,如图4所示:
图4,选中ArrayList.cst模板
双击该节点,便会弹出CodeSmith的输出窗口,在窗口的左边是属性输入框,您可以根据自己的需要设定各属性的值,然后只需轻轻点击下面的Generate按钮,CodeSmith就能立刻为您献上一份长长的源代码,如图5所示:
图5,使用CodeSmith生成源代码
该例子所生成的源代码共有2302行,想想如果手工输入这么多代码需要花费多少时间呢?而使用CodeSmith则仅花费了不到1分钟时间,其魅力则就不言而喻了!
如果您对CodeSmith提供的模板感到不太满意,或者您需要根据自己的需求来制作相应的模板,则可以使用CodeSmith Studio来新建或编辑现有代码模板,例如,你对刚才我们使用到的ArrayList.cst模板感到不甚满意,觉得自己有更好的创意,那么你可以运行CodeSmith Studio,然后在右边的文件列表中找到并打开ArrayList.cst,还记得刚才我介绍的那些模板元素以及它们各自的特性和用途吗?好吧,现在就开始动手根据您自己的想法来完善这个模板吧。
图6,编辑代码模板
在这里因为篇幅有限,所以我只是使用了一个最简单的例子来向大家展示使用CodeSmith的好处,其实CodeSmith的强大远不仅仅是输出这样简单的代码文件,记住,CodeSmith是基于模板生成代码的,因此,套用那句“人有多大胆,地有多高产”的话来说就是:“模板有多强大,代码就有多丰富!”
Why
为什么向您推荐CodeSmith?可千万别把我当成了托儿,我可没有收取CodeSmith Tools LLC任何物质上以及精神上的报酬,不过是为了和广大开发着朋友们分享一款优秀的专业软件而已。
其实有很多代码都是不需要我们自己从头到尾亲自写一遍的,尤其是在工作中,为什么不能用更少的时间完成更多的事情呢?程序员从事的是脑力劳动,我们应该充分运用我们的头脑来找到解决问题的更快更好的办法,只有当我们能够很好地解决自己工作中的问题的时候,我们才能够为我们的用户提供能很好解决他们面临的问题的解决方案。