動軟模板其實和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 <#@ 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層模板-------------------