在CodeSmith 使用教程(1): 概述我們通過(guò)使用 CodeSmith 從數(shù)據(jù)庫(kù)自動(dòng)生成 NHiberate 代碼,可以了解到使用 CodeSmith 自動(dòng)生成代碼的基本步驟:
其核心為代碼模板文件,隨 CodeSmith 自帶了不少常用的模板,可以通過(guò)模板瀏覽器來(lái)查詢(xún),此外網(wǎng)上也有很多第三方開(kāi)發(fā)的模板,在使用前可以先查查是否已有現(xiàn)成的模板,或是可以通過(guò)修改現(xiàn)有的模板來(lái)完成自動(dòng)生成代碼的需要。
在開(kāi)發(fā)應(yīng)用時(shí),很多人都喜歡通過(guò)復(fù)制以前的項(xiàng)目中的代碼,然后通過(guò)修改以滿(mǎn)足新項(xiàng)目,這些重用的代碼通常具有很多共性(可以想想 C++ 的模板類(lèi),C# 的 Generic 等),CodeSmith 就是用來(lái)為這些具有相似性的代碼創(chuàng)建模板,然后通過(guò)設(shè)置屬性(代碼直接的不同點(diǎn)),就可以自動(dòng)創(chuàng)建所需代碼。
本例通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)介紹創(chuàng)建一個(gè)自定義代碼模板的方法。CodeSmith 提供了 Visual Studio的集成開(kāi)發(fā)環(huán)境的支持,本例也是通過(guò)創(chuàng)建模板自動(dòng)生成簡(jiǎn)化每個(gè)的 C# 項(xiàng)目都需要的 AssemblyInfo.cs,在開(kāi)發(fā) C# 應(yīng)用時(shí),一般是通過(guò)手工修改 AssemblyInfo.cs 的中屬性(或者是 Copy & Paste :-)).
首先我們使用 Visual Studio 創(chuàng)建一個(gè) C# HelloWorld 下面(Console 或是 WinForm 項(xiàng)目都可以),可以打開(kāi)項(xiàng)目中的 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,我們?cè)?HelloWorld 中添加 CodeSmith 的項(xiàng)目文件并創(chuàng)建一個(gè)模板文件AssemblyInfo.cst
創(chuàng)建好的項(xiàng)目文件如下:
編寫(xiě) CodeSmith 的代碼模板和編寫(xiě) Asp.Net 的 Page 非常類(lèi)似,CodeSmith 支持以 C#,VB.Net和 JavaScript 做為腳本語(yǔ)言來(lái)編寫(xiě)模板,本例使用 C# 做為腳本語(yǔ)言(源代碼/語(yǔ)言),計(jì)劃生成的也是 C# 語(yǔ)言(目標(biāo)代碼/語(yǔ)言),打開(kāi) AssemblyInfo.cst,修改代碼為
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Create an AssemblyInfo.cs file." %>
每個(gè) CodeSmith 的代碼模板都是以 CodeTemplate 開(kāi)始,定義代碼模板使用的源語(yǔ)言,目標(biāo)語(yǔ)言和簡(jiǎn)單的描述。
然后將這個(gè)模板添加到 CodeSmith 項(xiàng)目中,可以右鍵單擊 codesmith.csp ,選擇 Add output
這時(shí) CodeSmith 的項(xiàng)目將創(chuàng)建好了,但單擊”Generate code”不會(huì)生成任何代碼,因?yàn)槲覀兊拇a模板 AssemblyInfo.cst 沒(méi)做任何事。
創(chuàng)建代碼模板可以從生成的結(jié)果開(kāi)始,可以直接先把要生成的代碼復(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)容分成三部分:
此時(shí)如果使用 Codesmith 的 Generate Codes, 將自動(dòng)生成 AssemblyInfo.cs (缺省為模板名),不過(guò) AssemblyInfo.cs 位置不是我們所需的 Properties/AssemblyInfo.cs, 這可以通過(guò)重載代碼模板的 GetFileName 方法來(lái)實(shí)現(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 項(xiàng)目的 Generate Codes,就自動(dòng)覆蓋原來(lái)的 Properties/AssemblyInfo.cs 文件。 內(nèi)容就是模板中的代碼部分。
但每次生成的代碼都是固定的,作為模板來(lái)說(shuō)沒(méi)有什么靈活性,下面我們可以通過(guò)檢查模板的內(nèi)容,覺(jué)定那些內(nèi)容是可變的。比如 AssemblyInfo.cs 的日期和 Assembly 的各個(gè)屬性對(duì)于不同的項(xiàng)目來(lái)說(shuō)是可變的。
這些可變的內(nèi)容其中一部分可以通過(guò)代碼自動(dòng)生成(如日期),有一部分需要用戶(hù)來(lái)配置,比如AssemblyTitle,AssemblyDescription 等。
對(duì)于日期部分可以通過(guò)C#代碼實(shí)現(xiàn)如下:
// Created: <%= DateTime.Now.ToLongDateString() %>
可以看出來(lái) CodeSmith 的模板文件如 AssemblyInfo.cst 和 Asp.Net 的 Page 文件中功能是非常類(lèi)似,可以通過(guò)<%= 和%>直接嵌入 C# 代碼(或 VB.Net,JavaScripts)。
對(duì)于屬性來(lái)說(shuō),可以通過(guò)先定義屬性:
<%@ 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." %>
屬性定義通過(guò) Property 定義,Name 定義屬性名,Type 為屬性的數(shù)據(jù)類(lèi)型,Default 定義屬性的缺省值, Description 可以定義屬性的作用及說(shuō)明。
然后就可以在 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)]
此時(shí)如果需要“Generate output” 首先要配置代碼模板的屬性,這通過(guò)”Manage output” 來(lái)完成,
次數(shù)如果打開(kāi) codesmith.csp 文件可以看到為 AssemblyInfo.cst 配置的屬性?xún)?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)]
本例下載
更多建議: