使用 T4 生产代码
T4 是:
就是 4 个T - Text Transformation Templating Tool, 意思就是用写文本的方式来写模板。
俗话说:VS2008 已经内置了 T4。是这么证明的:新建一个扩展名为.tt的文本文件,会自动生成一个相应的 cs 文件,通过修改tt文本内部的输出扩展名(如<#@ output extension=".xml" #>),就能生成 xml 之类的文件。
其实,想要真正使用T4 来生成代码,就不是这么简单了(其实也很简单)... 通过他内置的那些语法什么的,仿佛不足以生成一个可以使用的代码。
现在——
打开 这个目录:F:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC\CodeTemplates\.. 这个目录,看看,下面的 .tt 文件。
俗话说:这个目录下的文件就是为 mvc 生产代码用的。语法很简单,相信大家一看就明白。
现在来看 Controller.tt 这个文件:
<#
MvcTextTemplateHost mvcHost = (MvcTextTemplateHost)(Host);
#>
MvcTextTemplateHost 这是个什么东东啊?赶紧查文档啊。
找到了这个网址:http://msdn.microsoft.com/en-us/library/bb126551.aspx
感觉到了,MvcTextTemplateHost 实现了这个接口 Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost 。Microsoft.VisualStudio.TextTemplating 这个命名空间存在于:Microsoft.VisualStudio.TextTemplatin.dll,这个dll 存在于 vs sdk,所以就不废话了,赶紧下载 vs sdk 吧,在下面的地址:
http://www.microsoft.com/downloads/details.aspx?FamilyID=30402623-93ca-479a-867c-04dc45164f5b&displaylang=en (1.0) 我用的这个测试的,安装1.1 还要卸载1.0,累死咯。
http://www.microsoft.com/downloads/details.aspx?familyid=59EC6EC3-4273-48A3-BA25-DC925A45584D&displaylang=en(1.1)
下载......
安装......
以下是实验过程:
1、新建一个项目(Console的就行咯)
2、添加一个 类 文件,冒号这个接口:Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ,当然要引用 Microsoft.VisualStudio.TextTemplating 这个包包了,安装sdk后这个包包就有了。
3、自动实现一下那些接口,重点说一下这几个。
///这个是你要生产的代码的扩展名
private string fileExtensionValue = ".txt";
public string FileExtension
{
get { return fileExtensionValue; }
}
//这个是你的代码中要引入的包包,这个例子中引入了 System.dll 和 本项目的 dll,
//如果你不想引用,那么就得在 你的 tt 文件中引入
public IList<string> StandardAssemblyReferences
{
get
{
return new string[]
{
typeof(System.Uri).Assembly.Location,
typeof(CustomCmdLineHost).Assembly.Location
};
}
}
//这个是你的代码中要using 的命名空间,这个例子中引入了 System 和 本项目的,
//如果你不想引用,那么就得在 你的 tt 文件中写
public IList<string> StandardImports
{
get
{
return new string[]
{
"System",
"CustomHost"
};
}
}
这个写完了,基本就完成了。
好,现在就可以往这个类里面加入自己的东西了,就像MVC里面的那样,加入两个变量(属性):
public string NameSpace = "Cloudbeer";
public string ItemName = "Love";
调用的代码是:
CustomCmdLineHost host = new CustomCmdLineHost();
Engine engine = new Engine();
host.TemplateFileValue = templateFileName;
//Read the text template.
string input = File.ReadAllText(templateFileName);
//Transform the text template.
string output = engine.ProcessTemplate(input, host);
现在来看我写的tt 文件:
<#
CustomHost.CustomCmdLineHost host = (CustomHost.CustomCmdLineHost)(Host);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
namespace <#= host.NameSpace #>
{
public class <#= host.ItemName #> : Controller
{
<# for (int i=0; i<3; i++)
{
WriteLine(" //This is a test");
}
#>
}
}
在命令行下运行:
D:\Project Test\CustomHost\CustomHost\bin\Debug>CustomHost.exe Test.tt
得到结果为
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
namespace Cloudbeer
{
public class Love : Controller
{
//This is a test
//This is a test
//This is a test
}
}
hoho,现在应该搞定了吧,接下来,我要把这个东西应用到我的“代码生成器”了。
我把这个测试的解决方案贴在这里 :
参考文献:
大部分都抄自本地版的 MSDN。