T4:T4 笔记 + Trait 示例

时间:2023-03-09 13:13:31
T4:T4 笔记 + Trait 示例

背景

官方教程:http://msdn.microsoft.com/en-us/library/vstudio/bb126445.aspx

如果开发环境或编译器内置了对模板的支持而没有善加利用,就算是一只浪费了。简单的使用模板就是代码生成器,也可以更细致的使用模板,比如模拟Trait。

Trait示例

Dog

 namespace T4Study.Trait
{
public partial class Dog
{
public string Name { get; set; }
}
}

Man

 namespace T4Study.Trait
{
public partial class Man
{
public string Name { get; set; }
}
}

Trait

 <#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #> <# Trait(() => { #>
public void Play()
{
System.Console.WriteLine(this.Name + ",游戏中!");
}
<# }, "T4Study.Trait.Dog", "T4Study.Trait.Man"); #> <#@include file="../Includes/Trait.txt" #>

测试

         static void Main(string[] args)
{
var man = new Trait.Man { Name = "段光伟" };
var dog = new Trait.Dog { Name = "旺仔" }; man.Play();
dog.Play();
}

总结

本例中,接口 + 扩展类型 可以做到同样的效果,T4 + 部分类 为我们提供了另外一种选择。

设计时代码生成

官方教程:http://msdn.microsoft.com/en-us/library/vstudio/dd820620.aspx

使用相对路径(相对于模板)获取文件或目录的路径

hostspecific 设置为 true

 <#@ template debug="false" hostspecific="true" language="C#" #>

使用 this.Host.ResolvePath(相对路径)

 <#= this.Host.ResolvePath("Class.Data.txt") #>

获取当前模板的路径

hostspecific 设置为 true,使用 this.Host.TemplateFile

 <#= this.Host.TemplateFile #>

访问开发环境

hostspecific 设置为 true,引用 EnvDTE

 <#@ assembly name="EnvDTE" #>

获取 EnvDTE.DTE 实例

 <#
IServiceProvider serviceProvider = (IServiceProvider)this.Host;
EnvDTE.DTE dte = (EnvDTE.DTE) serviceProvider.GetService(typeof(EnvDTE.DTE));
#> 项目总数:<#= dte.Solution.Projects.Count #>

向VS报告错误

 this.Error("错误信息");
this.Warning("警告信息");

定义帮助方法

 <#+
private string UpperInitial(string name)
{
return name[].ToString().ToUpperInvariant() + name.Substring();
}
#>

复用模板片段

1 <#@include file="../Includes/Header.txt" #>

复用的片段里可以有任何模板里可以包含的内容,复用的片段里还可以再包含其它复用的片段。

运行时代码生成

官方教程:http://msdn.microsoft.com/en-us/library/vstudio/ee844259.aspx

引用程序集

在VS中添加对程序集的引用即可,这里和设计时代码生成不一样(使用 <#@ assembly name="System.Core" #>)。

定义帮助方法

 <#+
private string UpperInitial(string name)
{
return name[].ToString().ToUpperInvariant() + name.Substring();
}
#>

和设计时代码生成不同的是,在部分类里可以定义任何类型成员。

复用模板片段

 <#@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. 转义<##>:\<# ... \#>。

备注

官方永远是最好的教程,本文只记录了一些关键点,主要为了方便快速查阅。