背景
官方教程:http://msdn.microsoft.com/en-us/library/vstudio/bb126445.aspx。
如果開發環境或編譯器內置了對模板的支持而沒有善加利用,就算是一只浪費了。簡單的使用模板就是代碼生成器,也可以更細致的使用模板,比如模擬Trait。
Trait示例
Dog
1 namespace T4Study.Trait 2 { 3 public partial class Dog 4 { 5 public string Name { get; set; } 6 } 7 }
Man
1 namespace T4Study.Trait 2 { 3 public partial class Man 4 { 5 public string Name { get; set; } 6 } 7 }
Trait
1 <#@ template debug="false" hostspecific="false" language="C#" #> 2 <#@ assembly name="System.Core" #> 3 <#@ import namespace="System.Linq" #> 4 <#@ import namespace="System.Text" #> 5 <#@ import namespace="System.Collections.Generic" #> 6 <#@ output extension=".cs" #> 7 8 <# Trait(() => { #> 9 public void Play() 10 { 11 System.Console.WriteLine(this.Name + ",游戲中!"); 12 } 13 <# }, "T4Study.Trait.Dog", "T4Study.Trait.Man"); #> 14 15 <#@include file="../Includes/Trait.txt" #>
測試
1 static void Main(string[] args) 2 { 3 var man = new Trait.Man { Name = "段光偉" }; 4 var dog = new Trait.Dog { Name = "旺仔" }; 5 6 man.Play(); 7 dog.Play(); 8 }
總結
本例中,接口 + 擴展類型 可以做到同樣的效果,T4 + 部分類 為我們提供了另外一種選擇。
設計時代碼生成
官方教程:http://msdn.microsoft.com/en-us/library/vstudio/dd820620.aspx。
使用相對路徑(相對於模板)獲取文件或目錄的路徑
hostspecific 設置為 true
1 <#@ template debug="false" hostspecific="true" language="C#" #>
使用 this.Host.ResolvePath(相對路徑)
1 <#= this.Host.ResolvePath("Class.Data.txt") #>
獲取當前模板的路徑
hostspecific 設置為 true,使用 this.Host.TemplateFile
1 <#= this.Host.TemplateFile #>
訪問開發環境
hostspecific 設置為 true,引用 EnvDTE
1 <#@ assembly name="EnvDTE" #>
獲取 EnvDTE.DTE 實例
1 <# 2 IServiceProvider serviceProvider = (IServiceProvider)this.Host; 3 EnvDTE.DTE dte = (EnvDTE.DTE) serviceProvider.GetService(typeof(EnvDTE.DTE)); 4 #> 5 6 項目總數:<#= dte.Solution.Projects.Count #>
向VS報告錯誤
1 this.Error("錯誤信息"); 2 this.Warning("警告信息");
定義幫助方法
1 <#+ 2 private string UpperInitial(string name) 3 { 4 return name[0].ToString().ToUpperInvariant() + name.Substring(1); 5 } 6 #>
復用模板片段
1 <#@include file="../Includes/Header.txt" #>
復用的片段里可以有任何模板里可以包含的內容,復用的片段里還可以再包含其它復用的片段。
運行時代碼生成
官方教程:http://msdn.microsoft.com/en-us/library/vstudio/ee844259.aspx。
引用程序集
在VS中添加對程序集的引用即可,這里和設計時代碼生成不一樣(使用 <#@ assembly name="System.Core" #>)。
定義幫助方法
1 <#+ 2 private string UpperInitial(string name) 3 { 4 return name[0].ToString().ToUpperInvariant() + name.Substring(1); 5 } 6 #>
和設計時代碼生成不同的是,在部分類里可以定義任何類型成員。
復用模板片段
1 <#@include file="../Includes/Header.txt" #>
復用的片段里可以有任何模板里可以包含的內容,復用的片段里還可以再包含其它復用的片段。
繼承父模板
使用 inherits 繼承父模板
<#@ template language="C#" inherits="BaeTemplate" #>
模板慣用法
官方教程:http://msdn.microsoft.com/en-us/library/vstudio/bb126478.aspx。
慣用法:
- 使用<#@include #>指令 + <#+ #> 進行復用。
It is particularly useful to place a method that generates text in a separate file that can be included by more than one template. - 在<#@ assembly #>中可以使用宏名稱:<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>。
- 轉義<##>:\<# ... \#>。
備注
官方永遠是最好的教程,本文只記錄了一些關鍵點,主要為了方便快速查閱。