我们可以在CodeSmith中制定模板(当然这些模板是可以重复使用的),然后输入一些参数,最后生成所需的代码脚本。这就是CodeSmith大体的工作流程啦。
我认为CodeSmith最核心的思想是将一个代码文件中的内容分解成几个部分,即:
固定不变的内容(Content that will never change);
可自动产生的内容(Content that can be automatically generated);
可让用户指定的内容(Content that you will prompt the user for)。
固定不变的内容主要是由一些固定格式的声明、定义和特定的方法调用,这些内容构成我们模板的大体结构。
可自动产生的内容主要是一些在代码生成时能自动产生的信息,如代码生成日期,这些信息我么可以通过调用方法来获得。
可让用户指定的内容则是由模板得到最终代码所需的一些参数,不同的参数导致由同一模板生成不同的实际代码,是从抽象到具体的桥梁。
下面一个简单的例子说明了以上三点。
<%--
Name: HelloWorldTemplate
Author: Aixe
Description: The is a simple template to help learn CodeSmith.
--%>
<%@ CodeTemplate Language="C#" TargetLanguage="C#"
Description="A simple template for Hello World program." %>
<%@ Property Name="NamespaceName" Type="System.String" Default="HelloWorld"
Optional="False" Category="Context" Description="A name for your namespace." %>
<%@ Property Name="ClassName" Type="System.String" Default="Program"
Optional="False" Category="Context" Description="A name for your class." %>
<%@ Property Name="ClassAccessibility" Type="AccessibilityEnum"
Optional="True" Category="Context" Description="The accessibility of your class." %>
<%@ Property Name="Author" Type="System.String"
Optional="False" Category="Customized" Description="Your name here." %>
<%@ Property Name="Words" Type="System.String" Default="Hello World!"
Optional="False" Category="Content" Description="Words to say." %>
<%@ Assembly Name="System.Data" %>
<%@ Import Namespace="System" %>
// This code is writen by: <%= Author %>
// Create at: <%= DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") %>
using System;
namespace <%= NamespaceName %>
{
<%= GetAccessibility() %> class <%= ClassName %>
{
static void Main(string[] args)
{
Console.WriteLine("<%= Words %>");
Greeting("<%= Author %>");
}
static void Greeting(string name)
{
Console.WriteLine(string.Format("Hello, {0}", name));
}
}
}
<script runat="template">
public enum AccessibilityEnum
{
Public,
Protected,
Private,
}
public string GetAccessibility()
{
switch(ClassAccessibility)
{
case AccessibilityEnum.Public: return "public";
case AccessibilityEnum.Protected: return "protected";
case AccessibilityEnum.Private: return "private";
default: return string.Empty;
}
}
</script>
整个模板大致分为3个部分:模板和属性声明,模板主体和脚本。
每个模板前面都有一个声明语句,标明模板使用的语言和目标语言: <%@ CodeTemplate Language="C#" TargetLanguage="C#"
Description="A simple template for Hello World program." %>
接下来声明了模板中用到的几个属性,分别是命名空间的名字(NamespaceName),类名(ClassName),类的访问类型(ClassAccessibility),这是一个枚举类型,在后面的脚本中有定义,作者(Author)和一句信息(Words)。这些信息都由用户自己来输入的。这里的一些属性给出了默认值。 <%@ Property Name="NamespaceName" Type="System.String" Default="HelloWorld"
Optional="False" Category="Context" Description="A name for your namespace." %>
<%@ Property Name="ClassName" Type="System.String" Default="Program"
Optional="False" Category="Context" Description="A name for your class." %>
<%@ Property Name="ClassAccessibility" Type="AccessibilityEnum"
Optional="True" Category="Context" Description="The accessibility of your class." %>
<%@ Property Name="Author" Type="System.String"
Optional="False" Category="Customized" Description="Your name here." %>
<%@ Property Name="Words" Type="System.String" Default="Hello World!"
Optional="False" Category="Content" Description="Words to say." %>
接下来定义代码的模板主体,这里的内容大多是不变的,需要变动的地方就通过嵌入一段代码来得到动态的内容。
其中namespace的名字使用的是NamespaceName这个属性的值,类名用的是ClassName的值,通过调用GetAccessibility()方法得到类的访问属性。这些属性值是用户来指定的。不难发现,其写法很像ASP.NET中的数据绑定。
注释中的Create at一句则是通过调用System.DateTime.Now来获得代码创建的时间,属于自动生成的部分。 // This code is writen by: <%= Author %>
// Create at: <%= DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") %>
using System;
namespace <%= NamespaceName %>
{
<%= GetAccessibility() %> class <%= ClassName %>
{
static void Main(string[] args)
{
Console.WriteLine("<%= Words %>");
Greeting("<%= Author %>");
}
static void Greeting(string name)
{
Console.WriteLine(string.Format("Hello, {0}", name));
}
}
}
我们在定义ClassAccessibility这个属性时,使用了自定义的枚举类型AccessibilityEnum,因此还要在脚本中声明之。另外由于public, protected和,private是C#里的关键字,所以枚举里面的首字母P不能小写。为了根据ClassAccessibility属性的值获得类的访问属性,还需编写GetAccessibility()方法。 <script runat="template">
public enum AccessibilityEnum
{
Public,
Protected,
Private,
}
public string GetAccessibility()
{
switch(ClassAccessibility)
{
case AccessibilityEnum.Public: return "public";
case AccessibilityEnum.Protected: return "protected";
case AccessibilityEnum.Private: return "private";
default: return string.Empty;
}
}
</script>
完成以上步骤后,一个简单的模板就做好了。编译之后,可在属性面板里看到我们自定义的属性在这里被列了出来:
输入Author属性再运行,就可得到我们需要的代码了。 // This code is writen by: Aixe
// Create at: 2009-08-02 10:52:24
using System;
namespace HelloWorld
{
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Greeting("Aixe");
}
static void Greeting(string name)
{
Console.WriteLine(string.Format("Hello, {0}", name));
}
}
}
更改属性之后可以生成不同的代码。
可以看出,写CodeSmith模板和写ASP.NET很类似,熟悉的同学应该能很快上手。以上就是对CodeSmith的一次小小的体验,当然CodeSmith还有很多强大的功能和用法,CodeSmith本身也为我们提供许多很有用的模板供我们学习和使用,具体可以参考CodeSmith的帮助文档或网上的一些资料。
转载于:https://www.cnblogs.com/tracydj/archive/2009/08/02/1536824.html