T4:T4 筆記 + Trait 示例


背景

官方教程: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

慣用法:

  1. 使用<#@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.
  2. 在<#@ assembly #>中可以使用宏名稱:<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>。
  3. 轉義<##>:\<# ... \#>。

備注

官方永遠是最好的教程,本文只記錄了一些關鍵點,主要為了方便快速查閱。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM