鍍金池/ 教程/ C++/ 編寫第一個代碼模板
使用主從代碼模板
CodeTemplateInfo 對象
引用其它文件或 .Net 類庫
編寫第一個代碼模板
Progress 對象
基本語法-使用注釋
基本語法-轉(zhuǎn)義Asp.Net標(biāo)記
調(diào)試
為 Yii Framework 創(chuàng)建生成 ActiveRecord 的代碼模板
基本語法-聲明和使用屬性
自動生成Yii Framework ActiveRecord類簡單模板
Merge 策略
使用 XMLProperty
CodeTemplate 對象
基本語法-CodeTemplate 指令
概述
使用 SchemaExplorer 來獲取數(shù)據(jù)庫定義

編寫第一個代碼模板

CodeSmith 使用教程(1): 概述我們通過使用 CodeSmith 從數(shù)據(jù)庫自動生成 NHiberate 代碼,可以了解到使用 CodeSmith 自動生成代碼的基本步驟:

  1. 選擇使用合適的模板,CodeSmith 隨開發(fā)包自帶了大量常用的模板,如果找不到合適的模板,CodeSmith 支持自定義模板。
  2. 為模板選擇合適的參數(shù)設(shè)置。
  3. 自動生成代碼(可以為任意類型的代碼,C#,Java, .XML 文本等)

http://wiki.jikexueyuan.com/project/codesmith/images/8.png" alt="第8張" />

其核心為代碼模板文件,隨 CodeSmith 自帶了不少常用的模板,可以通過模板瀏覽器來查詢,此外網(wǎng)上也有很多第三方開發(fā)的模板,在使用前可以先查查是否已有現(xiàn)成的模板,或是可以通過修改現(xiàn)有的模板來完成自動生成代碼的需要。

在開發(fā)應(yīng)用時,很多人都喜歡通過復(fù)制以前的項目中的代碼,然后通過修改以滿足新項目,這些重用的代碼通常具有很多共性(可以想想 C++ 的模板類,C# 的 Generic 等),CodeSmith 就是用來為這些具有相似性的代碼創(chuàng)建模板,然后通過設(shè)置屬性(代碼直接的不同點),就可以自動創(chuàng)建所需代碼。

本例通過一個簡單的例子來介紹創(chuàng)建一個自定義代碼模板的方法。CodeSmith 提供了 Visual Studio的集成開發(fā)環(huán)境的支持,本例也是通過創(chuàng)建模板自動生成簡化每個的 C# 項目都需要的 AssemblyInfo.cs,在開發(fā) C# 應(yīng)用時,一般是通過手工修改 AssemblyInfo.cs 的中屬性(或者是 Copy & Paste :-)).

首先我們使用 Visual Studio 創(chuàng)建一個 C# HelloWorld 下面(Console 或是 WinForm 項目都可以),可以打開項目中的 AssemblyInfo.cs

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("HelloWorld")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("HelloWorld")]
[assembly: AssemblyCopyright("Copyright ? Microsoft 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("72797715-64b9-4bab-a49f-f55e8a0a18d7")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

為了使用 CodeSmith,我們在 HelloWorld 中添加 CodeSmith 的項目文件并創(chuàng)建一個模板文件AssemblyInfo.cst

http://wiki.jikexueyuan.com/project/codesmith/images/9.png" alt="第9張" />

創(chuàng)建好的項目文件如下:

http://wiki.jikexueyuan.com/project/codesmith/images/10.png" alt="第10張" />

編寫 CodeSmith 的代碼模板和編寫 Asp.Net 的 Page 非常類似,CodeSmith 支持以 C#,VB.Net和 JavaScript 做為腳本語言來編寫模板,本例使用 C# 做為腳本語言(源代碼/語言),計劃生成的也是 C# 語言(目標(biāo)代碼/語言),打開 AssemblyInfo.cst,修改代碼為

<%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Create an AssemblyInfo.cs file." %>

每個 CodeSmith 的代碼模板都是以 CodeTemplate 開始,定義代碼模板使用的源語言,目標(biāo)語言和簡單的描述。

然后將這個模板添加到 CodeSmith 項目中,可以右鍵單擊 codesmith.csp ,選擇 Add output

http://wiki.jikexueyuan.com/project/codesmith/images/11.png" alt="第11張" />

這時 CodeSmith 的項目將創(chuàng)建好了,但單擊”Generate code”不會生成任何代碼,因為我們的代碼模板 AssemblyInfo.cst 沒做任何事。

創(chuàng)建代碼模板可以從生成的結(jié)果開始,可以直接先把要生成的代碼復(fù)制到代碼模板 AssemblyInfo.cst中,比如:

using System.Reflection;
using System.Runtime.CompilerServices;
//
// Created: 1/1/2013
// Author: James Shen
//
[assembly: AssemblyTitle("User storage utility")]
[assembly: AssemblyDescription("Helps manage data in Isolated Storage files.")]
[assembly: AssemblyConfiguration("Retail")]
[assembly: AssemblyCompany("Guidebee Pty Ltd, Inc.")]
[assembly: AssemblyProduct("StorageScan")]
[assembly: AssemblyCopyright("Copyright (c) Guidebee Pty Ltd.")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0")]
[assembly: AssemblyDelaySign(true)]

可以把要生成的代碼模板的內(nèi)容分成三部分:

  • 固定內(nèi)容
  • 可以通過代碼動態(tài)生成的部分(如上面的日期)
  • 需要用戶提供屬性配置的部分

此時如果使用 Codesmith 的 Generate Codes, 將自動生成 AssemblyInfo.cs (缺省為模板名),不過 AssemblyInfo.cs 位置不是我們所需的 Properties/AssemblyInfo.cs, 這可以通過重載代碼模板的 GetFileName 方法來實現(xiàn):

<%@ CodeTemplate Language="C#" TargetLanguage="C#"
  Description="Create an AssemblyInfo.cs file." %>
...
<script runat="template">
public override string GetFileName() {
    return "Properties/AssemblyInfo.cs";
}
</script>

這樣在使用 CodeSmith 項目的 Generate Codes,就自動覆蓋原來的 Properties/AssemblyInfo.cs 文件。 內(nèi)容就是模板中的代碼部分。

但每次生成的代碼都是固定的,作為模板來說沒有什么靈活性,下面我們可以通過檢查模板的內(nèi)容,覺定那些內(nèi)容是可變的。比如 AssemblyInfo.cs 的日期和 Assembly 的各個屬性對于不同的項目來說是可變的。

這些可變的內(nèi)容其中一部分可以通過代碼自動生成(如日期),有一部分需要用戶來配置,比如AssemblyTitle,AssemblyDescription 等。

對于日期部分可以通過C#代碼實現(xiàn)如下:

// Created: <%= DateTime.Now.ToLongDateString() %>

可以看出來 CodeSmith 的模板文件如 AssemblyInfo.cst 和 Asp.Net 的 Page 文件中功能是非常類似,可以通過<%= 和%>直接嵌入 C# 代碼(或 VB.Net,JavaScripts)。

對于屬性來說,可以通過先定義屬性:

<%@ Property Name="Author" Type="System.String" Description="Lead author of the project." %>
<%@ Property Name="Title" Type="System.String" Description="Title of the project." %>
<%@ Property Name="Description" Type="System.String" Description="Description of the project." %>
<%@ Property Name="Configuration" Type="System.String" Default="Debug" Description="Project configuration." %>
<%@ Property Name="Company" Type="System.String" Default="Guidebee Pty Ltd." %>
<%@ Property Name="Product" Type="System.String" Description="Product Name." %>
<%@ Property Name="Version" Type="System.String" Default="1.0.*" Description=".NET assembly version." %>
<%@ Property Name="FileVersion" Type="System.String" Default="1.0" Description="Win32 file version." %>

屬性定義通過 Property 定義,Name 定義屬性名,Type 為屬性的數(shù)據(jù)類型,Default 定義屬性的缺省值, Description 可以定義屬性的作用及說明。

然后就可以在 C# 代碼中使用這些屬性,完整的代碼模板如下:

<%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Create an AssemblyInfo.cs file." %>
<%@ Property Name="Author" Type="System.String" Description="Lead author of the project." %>
<%@ Property Name="Title" Type="System.String" Description="Title of the project." %>
<%@ Property Name="Description" Type="System.String" Description="Description of the project." %>
<%@ Property Name="Configuration" Type="System.String" Default="Debug" Description="Project configuration." %>
<%@ Property Name="Company" Type="System.String" Default="Guidebee Pty Ltd." %>
<%@ Property Name="Product" Type="System.String" Description="Product Name." %>
<%@ Property Name="Version" Type="System.String" Default="1.0.*" Description=".NET assembly version." %>
<%@ Property Name="FileVersion" Type="System.String" Default="1.0" Description="Win32 file version." %>
using System.Reflection;
using System.Runtime.CompilerServices;
//
// Created: <%= DateTime.Now.ToLongDateString() %>
// Author:  <%= Author %>
//
[assembly: AssemblyTitle("<%= Title %>")]
[assembly: AssemblyDescription("<%= Description %>")]
[assembly: AssemblyConfiguration("<%= Configuration %>")]
[assembly: AssemblyCompany("<%= Company %>")]
[assembly: AssemblyProduct("<%= Product %>")]
[assembly: AssemblyCopyright("Copyright (c) <%= DateTime.Now.Year.ToString() %> <%= Company %>")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("<%= Version %>")]
[assembly: AssemblyFileVersion("<%= FileVersion %>")]
[assembly: AssemblyDelaySign(true)]

此時如果需要“Generate output” 首先要配置代碼模板的屬性,這通過”Manage output” 來完成,

http://wiki.jikexueyuan.com/project/codesmith/images/12.png" alt="第12張" />

次數(shù)如果打開 codesmith.csp 文件可以看到為 AssemblyInfo.cst 配置的屬性內(nèi)容:

<?xml version="1.0" encoding="utf-8"?>
<codeSmith xmlns="http://www.codesmithtools.com/schema/csp.xsd">
  <propertySets>
    <propertySet name="AssemblyInfo" template="AssemblyInfo.cst">
      <property name="Configuration">Debug</property>
      <property name="Company">Guidebee Pty Ltd.</property>
      <property name="Version">1.0.*</property>
      <property name="FileVersion">1.0</property>
      <property name="Author">James Shen</property>
      <property name="Title">Code smith Demo</property>
      <property name="Description">My First Template code</property>
      <property name="Product">SandCastle</property>
    </propertySet>
  </propertySets>
</codeSmith>

生成代碼如下:

using System.Reflection;
using System.Runtime.CompilerServices;
//
// Created: Thursday, 3 January 2013
// Author:  James Shen
//
[assembly: AssemblyTitle("Code smith Demo")]
[assembly: AssemblyDescription("My First Template code")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCompany("Guidebee Pty Ltd.")]
[assembly: AssemblyProduct("SandCastle")]
[assembly: AssemblyCopyright("Copyright (c) 2013 Guidebee Pty Ltd.")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0")]
[assembly: AssemblyDelaySign(true)]

本例下載

上一篇:使用 XMLProperty下一篇:概述