1. 程式人生 > 實用技巧 >T4模板(04)

T4模板(04)

目錄:

  • T4概念
  • 文字模板兩種型別
  • 文字模板的組成
  • 案例

1.T4

一種可以由自己去自定義規則的程式碼生成器。可生成任何形式的文字檔案或供程式呼叫的字串。

注意:在VS中T4模板是沒有智慧提示和顏色標註的,可以安裝官方推薦外掛:tangibleT4EditorPlusModellingTools

1.1 文字模板有兩種型別

  • 設計時模版

  以便定義應用程式的部分原始碼和其他資源。讀取單個輸入檔案或資料庫中的資料的多個模板,並生成一些原始檔。 每個模板都生成一個檔案。

  ①向您的專案中新增"文字模板"檔案。

  ②新增純文字檔案並將其"自定義工具"屬性設定為"TextTemplatingFileGenerator"。

  • 執行時模版

  以便生成文字字串

  ①若要建立執行時模板,請向您的專案中新增"已預處理的文字模板"檔案。

  ②還可以新增純文字檔案並將其"自定義工具"屬性設定為"TextTemplatingFilePreprocessor"。

1.2 文字模板的組成

  • 指令

   ①模版指令

<#@ template debug="false" hostspecific="false" language="C#" #>  
 //可選,hostspecific如果將此特性設為true,則會將名為Host的屬性新增到由文字模板生成的類中。
是物件轉換引擎的宿主的引用,並宣告為Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost 型別。

   ②引數指令

<#@ parameter type="Full.TypeName" name="ParameterName" #>
//用來傳參,出現在執行時模板中

   ③輸出指令

<#@ output extension=".fileNameExtension" [encoding="encoding"] #>
//用於設定輸出檔案的字尾名和檔案編碼。extension:輸出副檔名,預設為".cs"encoding:檔案編碼,默值為utf-8。

   ④程式集指令

<#@ assembly name="System.Core" #>
程式集指令相當於VS裡面我們新增程式集引用的功能。T4模版的程式集引用是完全獨立的。
可以使用 $(variableName) 語法引用 Visual Studio的變數。幾個常用的變數:

$(SolutionDir):當前專案所在解決方案目錄

$(ProjectDir):當前專案所在目錄

$(TargetPath):當前專案編譯輸出檔案絕對路徑

$(TargetDir):當前專案編譯輸出目錄,即web專案的Bin目錄

   ⑤匯入指令

<#@ import namespace="namespace" #>
//import 指令允許您在不提供完全限定名稱的情況下引用另一個名稱空間中的元素。 它等效於 C# 中的 using。

   ⑥包含指令

<#@ include file="filePath" #>
//包含指令可以提高程式碼複用率,比如我們可以將一些常用的程式集、名稱空間引用放到一個檔案裡,使用時僅需要引用下即可

  ⑦文字塊

<#@ output extension=".txt" #>
Hello World!
//文字塊直接向輸出檔案插入文字。 文字塊沒有特殊格式。
  • 控制模組

控制塊是用於轉換模板的程式程式碼節

  ①標準控制塊

   生成輸出檔案部件的程式程式碼節。

<#可以混合使用任意數量的文字塊和標準控制塊。控制塊不能巢狀控制塊,以“<# ... #>”分隔
for(int i = 0; i < 4; i++)
{
Write(i + ", ");
}
Write("4");
#>
Hello!

//也可以交錯文字和程式碼,而不必使用顯式 Write() 語句。 以下示例輸出"Hello!"四次:

<#

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

{

#>

Hello!

<#

}

#>

  ②表示式控制塊

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

<#= 2 + 3 #>  //包含5。表示式控制塊以 <#= ... #> 符號分隔。

  ③類功能控制塊

   定義屬性、方法或不應包含在主轉換中的所有其他程式碼。常用於編寫幫助器函式。類功能塊位於單獨的檔案中,包含在多個文字模板中。

//宣告使用 以 <#+ ... #> 符號分隔
<#@ output extension=".txt" #>
Squares:
<#
for(int i = 0; i < 4; i++)
{
#>
The square of <#= i #> is <#= Square(i+1) #>.
<#
}
#>
That is the end of the list.
<#+ // 定義方法
private int Square(int i)
{
return i*i;
}
#>

1.3案例:建立模型

可以藉助 DbHelper.ttinclude 和 Manager.ttinclude 兩個第三方資源提高T4模板的開發效率。(安裝命令:Install-Package T4 -Version 2.0.1)

DbHelper.ttinclude 的主要方法:

  • DbHelper.GetDbTables() :獲取指定資料庫的所有表。
  • DbHelper.GetDbColumns():獲取指定表的所有列。

Manager.ttinclude 的主要方法:

  • Create(): 獲取該類的一個例項。
  • StartNewFile():新建一個檔案。
  • Process(true):生成檔案。

另外,資料庫的連線字串在Config類(DbHelper.ttinclude 檔案)中。

生成T4模板程式碼:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data.dll" #>
<#@ assembly name="System.Data.DataSetExtensions.dll" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#@ include file="../Common/CodeTemplates/DbHelper.ttinclude"#>
<#@ include file="../Common/CodeTemplates/Manager.ttinclude"#>
<#
var manager = Manager.Create(Host, GenerationEnvironment);
var tables=DbHelper.GetDbTables(Config.ConnectionString,Config.DbDatabase);
foreach (DbTable table in tables)
{
manager.StartNewFile(table.TableName+".cs");
#>
using System;
namespace Model
{
public class <#=table.TableName#>
{
<#
foreach(var col in DbHelper.GetDbColumns(Config.ConnectionString,Config.DbDatabase,table.TableName))
{
#>
public <#=col.CSharpType#><# if(col.CommonType.IsValueType && col.IsNullable){#>?<#}#> <#=col.ColumnName#> { get; set; }
<#
}
#>
}
}
<#
}
manager.Process(true);
#>