動軟模板其實和CodeSmith的模板差不多 實現的原理是一樣的,但是CodeSmith貌似只支援表生成,而且不夠“國人化”,所以打算研究下動軟的模板,如果熟練掌握後想必以後開發專案效率可以提高很多了;

這裡以典型三層的預設模板為例子:

-------------------------------------------------------------------------------------------------------------------------------------------------------

 <#@ template language="c#" HostSpecific="True" #>
<#@ output extension= ".cs" #>
<#
TableHost host = (TableHost)(Host);
host.Fieldlist.Sort(CodeCommon.CompareByintOrder);
#>
using System;
using System.Text;
using System.Collections.Generic;
using System.Data;
namespace <#= host.NameSpace #>.Model<# if( host.Folder.Length > ) {#>.<#= host.Folder #><# } #>
{
<# if( host.TableDescription.Length > ) {#>
//<#= host.TableDescription #>
<# } #>
public class <#= host.GetModelClass(host.TableName) #>
{ <# foreach (ColumnInfo c in host.Fieldlist)
{ #>/// <summary>
/// <#= string.IsNullOrEmpty(c.Description) ? c.ColumnName : c.Description #>
/// </summary>
private <#= CodeCommon.DbTypeToCS(c.TypeName) #> _<#= c.ColumnName.ToString().ToLower() #>;
public <#= CodeCommon.DbTypeToCS(c.TypeName) #> <#= c.ColumnName #>
{
get{ return _<#= c.ColumnName.ToString().ToLower()#>; }
set{ _<#= c.ColumnName.ToString().ToLower() #> = value; }
}
<# } #> }
}

模板的大體分為5塊內容:模板指令宣告,程式碼語句塊,表示式塊,類功能控制塊,文字塊輸出。下面我們分別來介紹一下這5塊內容的語法和使用說明。

  1. ----------------模板指令宣告塊 <#@  #>------------------------------

按行拆分:

1 <#@ template language="c#" HostSpecific="True" #>
2 <#@ output extension= ".cs" #>
講解:

<#@ template language="c#" HostSpecific="True" #>

模板指令宣告,template language="c#" 代表生成的是基於C#語言的模板,

hostSpecific="true" 表示是否使用特定的host,host裡面包含了模板使用的各種物件。 (這句一般預設即可)
<#@ output extension= ".cs" #>

這句代表是輸入.CS的檔案

              注意

所有屬性值(="c#",="True",= ".cs" ...)必須用雙引號都括起來。如果值本身包含引號,則必須使用 \ 字元對這些引號進行轉義。 指令通常是模板檔案或包含的檔案中的第一個元素(所有模板必須要有這兩句)。

---------關於此塊官方更詳細的講解(一般只用到上面這兩句就可以了)---------------

和ASP.NET頁面的指令一樣,它們出現在檔案頭,通過<#@…#>表示。其中<#@ template …#>指令是必須的,用於定義模板的基本屬性。

(1)    模板指令

<#@ template [language="VB"] [hostspecific="true"] [debug="true"] [inherits="templateBaseClass"] [culture="code"] [compilerOptions="options"] #>

例如

<#@ template language="C#v3.5" hostSpecific="true" debug="true" #>

Language  這裡可以指定模板使用的語言。

hostSpecific="true" 表示是否使用特定的host,host裡面包含了模板使用的各種物件。

注意

所有屬性值必須用雙引號都括起來。如果值本身包含引號,則必須使用 \ 字元對這些引號進行轉義。 指令通常是模板檔案或包含的檔案中的第一個元素。

(2)    引數指令

<#@ parameter type="Full.TypeName" name="ParameterName" #>

(3)    輸出指令

<#@ output extension=".fileNameExtension"  encoding="encoding"  #>

  • output extension=".cs"   指定生成檔案的副檔名。

encoding="encoding"    指定生成檔案的編碼。

(4)    程式集指令

<#@ assembly name="System.Data" #>

用於新增程式集引用,如果要使用第三方程式集,那麼最好在專案中新增引用。

注:您應使用絕對路徑的名稱,或者路徑名稱中使用標準的巨集的名稱。

例如: <#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>

(5)    匯入指令

<#@ import namespace="System.Data" #>

匯入要使用的名稱空間,注意:這裡的名稱空間必須要在前面指定的程式集裡面找得到的,比如我指定名稱空間"System.Data","System.Data.Common",這些在程式集System.Data中都有的

(6)    包含指令

<#@ include file="test.tt" #> 匯入模板,類似Html的include用法

include 指令插入其他模板檔案的文字。

例如,下面的指令插入 test.txt 的內容。 <#@ include file="c:\test.txt" #>

在處理時,被包含內容就像是包含文字模板的組成部分一樣。 不過,即使 include 指令後跟普通文字塊和標準控制塊,也可以包含編寫有類功能塊 <#+...#> 的檔案

--------------------2.程式碼語句塊: <#   #>--------------------------------

在模板檔案中,可以混合使用任意數量的文字塊和標準控制塊。中間是一段通過相應程式語言編寫的程式呼叫,我們可以通過程式碼語句塊控制文字轉化的流程。

注意:不能在控制塊中巢狀控制塊。

<#@ output extension=".txt" #>

<#

for(int i = 0; i < 4; i++)

{

#>

Hello!

<#

}

#>

------------------看預設的Model模板:-------------

3 <#
4     TableHost host = (TableHost)(Host);
5     host.Fieldlist.Sort(CodeCommon.CompareByintOrder);
6 #>
  ---------------------

TableHost host = (TableHost)(Host);

這句應該是建立host物件,以便呼叫host物件下的一系列方法和屬性等,類似於C#的New;

host.Fieldlist.Sort(CodeCommon.CompareByintOrder);

Fieldlist = 欄位集合,型別為List<ColumnInfo>,ColumnInfo=欄位資訊物件;

CodeCommon 是個工具類, CompareByintOrder 這個官方沒有給出說明;

這句的意思是取得欄位列表並按照一定順序排序;

--------------------------------------------

7 using System;
8 using System.Text;
9 using System.Collections.Generic;
10 using System.Data;

這些都是固定的名稱空間,文字按原樣輸出!!!

------------官方註解和示例:---

5.文字塊輸出

可以使用 Write() 和 WriteLine() 方法在標準程式碼塊內追加文字,而不必使用表示式程式碼塊。 它們可幫助縮排輸出和報告錯誤。

下面兩個程式碼塊在功能上是等效的。

包含表示式塊的程式碼塊

<#

int i = 10;

while (i-- > 0)

{ #>

<#= i #>

<# }

#>

使用 WriteLine() 的程式碼塊

<#

int i = 10;

while (i-- > 0)

{

WriteLine((i.ToString()));

}

#>

Write() 和 WriteLine() 方法有兩個過載,其中一個過載接受單個字串引數,另一個過載接受一個複合格式字串以及將包含在字串中的物件陣列(與 Console.WriteLine() 方法類似)。

下面兩種 WriteLine() 用法在功能上是等效的:

<#

string msg = "Say: {0}, {1}, {2}";

string s1 = "hello";

string s2 = "goodbye";

string s3 = "farewell";

WriteLine(msg, s1, s2, s3);

WriteLine("Say: hello, goodbye, farewell");

#>

設定文字模板輸出縮排的格式。

CurrentIndent 字串屬性顯示文字模板中的當前縮排,該類還具有一個 indentLengths 欄位,該欄位是已新增的縮排的列表。

PushIndent() 方法增加縮排,

PopIndent() 方法減少縮排。

ClearIndent() 方法,刪除所有縮排。

下面的程式碼塊演示這些方法的用法:

<#

WriteLine(CurrentIndent + "Hello");

PushIndent("    ");

WriteLine(CurrentIndent + "Hello");

PushIndent("    ");

WriteLine(CurrentIndent + "Hello");

ClearIndent();

WriteLine(CurrentIndent + "Hello");

PushIndent("    ");

WriteLine(CurrentIndent + "Hello");

#>

此程式碼塊產生以下輸出:

Hello

Hello

Hello

Hello

Hello

------------------------------------

11 namespace <#= host.NameSpace #>.Model<# if( host.Folder.Length > 0) {#>.<#= host.Folder #><# } #>

名稱空間:這句比較簡單,host.NameSpace 獲取host物件的名稱空間,以及是否加字尾(一般是沒有後綴了...,Folder 官方解釋是所屬資料夾的意思,型別是字串,這裡不太明白希望有人講解下);

12 {
13     <# if( host.TableDescription.Length > 0) {#>
14      //<#= host.TableDescription #>
15     <# } #>

如果此表有描述資訊,將在此顯示:如

/// <summary>
 /// 廣告管理  (表描述)
 /// </summary>

16     public class <#= host.GetModelClass(host.TableName) #>
17     {

根據表名獲取Model類名

官方註解:

3.表示式塊:<#=  #>

表示式控制塊計算表示式並將其轉換為字串。 該字串將插入到輸出檔案中。

例如: <#= 2 + 3 #>

表示式可以包含作用域中的任何變數。 例如,下面的塊輸出數字行:

<#@ output extension=".txt" #>

<#

for(int i = 0; i < 4; i++)

{

#>

This is hello number <#= i+1 #>: Hello!

<#

}

#>

-------------------------------

18                
19           <# foreach (ColumnInfo c in host.Fieldlist)
20         { #>/// <summary>
21         /// <#= string.IsNullOrEmpty(c.Description) ? c.ColumnName : c.Description #>
22         /// </summary>       
23         private <#= CodeCommon.DbTypeToCS(c.TypeName) #> _<#= c.ColumnName.ToString().ToLower() #>;
24         public <#= CodeCommon.DbTypeToCS(c.TypeName) #> <#= c.ColumnName #>
25         {
26             get{ return _<#= c.ColumnName.ToString().ToLower()#>; }
27             set{ _<#= c.ColumnName.ToString().ToLower() #> = value; }
28         }       
29         <# } #>
30   
31     }
32 }

<# foreach (ColumnInfo c in host.Fieldlist)

遍歷欄位集合

<#= string.IsNullOrEmpty(c.Description) ? c.ColumnName : c.Description #>

欄位說明不為空的話在此顯示

private <#= CodeCommon.DbTypeToCS(c.TypeName) #> _<#= c.ColumnName.ToString().ToLower() #>;

DbTypeToCS = 得到“資料庫欄位型別”對應的“c#型別”

這句是得到資料庫欄位型別對應的C#型別 並新增“_”: 如 private int  _id;

24         public <#= CodeCommon.DbTypeToCS(c.TypeName) #> <#= c.ColumnName #>  
25         {
26             get{ return _<#= c.ColumnName.ToString().ToLower()#>; }
27             set{ _<#= c.ColumnName.ToString().ToLower() #> = value; }
28         }        
29         <# } #>

設定屬性,同樣是獲取對應的C#型別 並設定 get set的值(與下劃線的欄位相對應);

-----------------------------------下篇介紹DAL層模板-------------------