T4文本模板转换过程
T4文本模板转换过程将文本模板文件作为输入,生成一个新的文本文件作为输出。 例如,可以使用文本模板生成 Visual Basic 或 C# 代码,还可以生成 HTML 报告。
有三个组件参与这一过程:引擎、宿主和指令处理器。 引擎对该过程进行控制(引擎与宿主和指令处理器交互),以生成输出文件;宿主提供与环境的所有交互(如定位文件和程序集); 指令处理器为文本模板添加功能(如从 XML 文件或数据库读取数据等)。
组件:
组件 | 说明 | 可自定义(是/否) |
引擎 | 引擎组件控制文本模板转换过程。 | 否 |
主机 | 宿主是引擎与用户环境之间的接口。 Visual Studio 是文本转换过程的宿主。 | 是。 可以编写自定义宿主。 |
指令处理器 | 指令处理器是处理文本模板中的指令的类。 可以使用指令从输入源向文本模板提供数据。 | 是。 可以编写自定义指令处理器。 |
引擎:
引擎以字符串形式从宿主接收模板,而宿主处理在转换过程中所用的所有文件。 接下来,引擎请求宿主定位所有自定义指令处理器和环境中的其他方面。 然后,引擎编译和运行生成转换类。 引擎将生成的文本返回给宿主,宿主通常将该文本保存到文件中。
宿主:
宿主负责转换过程之外与环境有关的所有操作,包括:
1)查找引擎或指令处理器请求的文本和二进制文件。 宿主可以搜索目录和全局程序集缓存以查找程序集。 宿主可以为引擎查找自定义指令处理器代码。 宿主还可以查找并读取文本文件,然后以字符串形式返回其内容。
2)提供标准程序集和命名空间的列表,供引擎用于创建生成转换类。
3)提供引擎在编译和执行生成转换类时所用的应用程序域。 将使用独立应用程序域,以免宿主应用程序受到模板代码错误的影响。
4)写入生成的输出文件。
5)设置生成的输出文件的默认扩展名。
6)处理文本模板转换错误。 例如,宿主可以将错误显示在用户界面中,也可以将错误写入文件。 (在 Visual Studio 中,错误显示在“错误消息”窗口中。)
7)在用户调用了指令但未提供值时,提供必需的参数值。 指令处理器可以指定指令名称和参数,可以请求宿主提供默认值(如果有)。
指令和指令处理器:
指令是文本模板中的命令。 它向生成过程提供参数。 通常,指令定义模型或其他输入的源和类型,以及输出文件的文件扩展名等。
指令处理器可以处理一个或多个指令。 转换模板之前,必须安装能够处理模板中的指令的指令处理器。
有了基本的概念,我们看下面的Demo(在程序中动态执行T4模板):
在程序中动态执行T4模板:
执行结果:
CustomTextTemplatingEngineHost.cs(自定义文本模板宿主)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TextTemplating;
using System.CodeDom.Compiler;
using System.IO;
namespace CustomHost
{
public class CustomTextTemplatingEngineHost : ITextTemplatingEngineHost, ITextTemplatingSessionHost
{
#region ITextTemplatingEngineHost
internal string TemplateFileValue;
public string TemplateFile
{
get { return TemplateFileValue; }
}
private string fileExtensionValue = ".txt";
public string FileExtension
{
get { return fileExtensionValue; }
}
private Encoding fileEncodingValue = Encoding.UTF8;
public Encoding FileEncoding
{
get { return fileEncodingValue; }
}
private CompilerErrorCollection errorsValue;
public CompilerErrorCollection Errors
{
get { return errorsValue; }
}
public IList<string> StandardAssemblyReferences
{
get
{
return new string[]
{
typeof(System.Uri).Assembly.Location
};
}
}
public IList<string> StandardImports
{
get
{
return new string[]
{
"System"
};
}
}
public bool LoadIncludeText(string requestFileName, out string content, out string location)
{
content = System.String.Empty;
location = System.String.Empty;
if (File.Exists(requestFileName))
{
content = File.ReadAllText(requestFileName);
return true;
}
else
{
return false;
}
}
public object GetHostOption(string optionName)
{
object returnObject;
switch (optionName)
{
case "CacheAssemblies":
returnObject = true;
break;
default:
returnObject = null;
break;
}
return returnObject;
}
public string ResolveAssemblyReference(string assemblyReference)
{
if (File.Exists(assemblyReference))
{
return assemblyReference;
}
string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference);
if (File.Exists(candidate))
{
return candidate;
}
return "";
}
public Type ResolveDirectiveProcessor(string processorName)
{
if (string.Compare(processorName, "XYZ", StringComparison.OrdinalIgnoreCase) == 0)
{
//return typeof();
}
throw new Exception("Directive Processor not found");
}
public string ResolvePath(string fileName)
{
if (fileName == null)
{
throw new ArgumentNullException("the file name cannot be null");
}
if (File.Exists(fileName))
{
return fileName;
}
string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), fileName);
if (File.Exists(candidate))
{
return candidate;
}
return fileName;
}
public string ResolveParameterValue(string directiveId, string processorName, string parameterName)
{
if (directiveId == null)
{
throw new ArgumentNullException("the directiveId cannot be null");
}
if (processorName == null)
{
throw new ArgumentNullException("the processorName cannot be null");
}
if (parameterName == null)
{
throw new ArgumentNullException("the parameterName cannot be null");
}
return String.Empty;
}
public void SetFileExtension(string extension)
{
fileExtensionValue = extension;
}
public void SetOutputEncoding(System.Text.Encoding encoding, bool fromOutputDirective)
{
fileEncodingValue = encoding;
}
public void LogErrors(CompilerErrorCollection errors)
{
errorsValue = errors;
}
public AppDomain ProvideTemplatingAppDomain(string content)
{
return AppDomain.CreateDomain("Generation App Domain");
}
#endregion
#region ITextTemplatingSessionHost
public ITextTemplatingSession CreateSession()
{
return Session;
}
public ITextTemplatingSession Session
{
get;
set;
}
#endregion
}
}
“执行”按钮单击-》(T4文本模板转换过程)
CustomTextTemplatingEngineHost host = new CustomTextTemplatingEngineHost();
host.TemplateFileValue = txtPath.Text;
string input = File.ReadAllText(txtPath.Text);
host.Session = new TextTemplatingSession();
host.Session.Add("hzx", new People("韩兆新", 24, "男"));
string output = new Engine().ProcessTemplate(input, host);
txtResult.Text = output;
StringBuilder errorWarn = new StringBuilder();
foreach (CompilerError error in host.Errors)
{
errorWarn.Append(error.Line).Append(":").AppendLine(error.ErrorText);
}
txtError.Text = errorWarn.ToString();
申明People类可序列化(传递参数的类型)
[Serializable]
public class People
{
public People(string name, uint age, string sex)
{
this.Name = name;
this.Age = age;
this.Sex = sex;
}
public string Name
{ set; get; }
public uint Age
{ set; get; }
public string Sex
{ set; get; }
}
test.tt
<#@template debug="false" hostspecific="false" language="C#"#>
<#@ output extension=".txt" encoding="utf-8" #>
<#@ parameter type="Demo_T4.People" name="hzx" #>
Name:<#= hzx.Name #> Age:<#= hzx.Age #> Sex:<#= hzx.Sex #>
T4文本模板转换过程的更多相关文章
- 一个简单的代码生成器(T4文本模板运用)
说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了.今天痛定思痛,终于把这件拖了很久的事做了.好,不废话了,现在看看"一个简单的代码生成器" ...
- 编写 T4 文本模板
文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板 ...
- T4 文本模板编写准则
如果要在 Visual Studio 中生成程序代码或其他应用程序资源,遵守以下一般准则可能非常有帮助. 它们并不是一成不变的规则. 设计时 T4 模板准则 设计时 T4 模板是在设计时在 Visua ...
- 使用 T4 文本模板生成设计时代码
使用设计时 T4 文本模板,您可以在 Visual Studio 项目中生成程序代码和其他文件. 通常,您编写一些模板,以便它们根据来自模型的数据来改变所生成的代码. 模型是包含有关应用程序要求的 ...
- T4文本模板
<#...#> 可以包含语句 <#=...#> 用于表达式,提供“输出”操作 <#+ ...> 使用类功能控制块向文本模板添加方法.属性.字段,必须作为文件中最后 ...
- MVC开发T4代码生成之一----文本模板基础
T4文本模板 T4全写为Text Template Transformation Toolkit,是一种编程辅助工具,用来使程序代码自(懒)动(猿)生(福)成(利)的工具.MVC开发中大量使用了T4模 ...
- C#代码生成工具:文本模板初体验 使用T4批量修改实体框架(Entity Framework)的类名
转自:http://www.cnblogs.com/huangcong/archive/2011/07/20/1931107.html 在之前的文本模板(T4)初体验中我们已经知道了T4的用处,下面就 ...
- T4((Text Template Transformation Toolkit))模版引擎之基础入门 C#中文本模板(.tt)的应用
1 关于C#中文本模板(.tt)的简单应用https://blog.csdn.net/zunguitiancheng/article/details/78011145 任何一个傻瓜都能写出计算机能理解 ...
- T4模板之文本模板
网址:https://docs.microsoft.com/en-us/visualstudio/modeling/design-time-code-generation-by-using-t4-te ...
随机推荐
- 【linux】ubuntu中上下左右键变为^[[A^[[B^[[D^[[C问题处理
问题现象: 使用上下左右键时,结果为 ^[[A^[[B^[[D^[[C,如图: 原因在于ubuntu系统自带的 vi 不完整导致. 解决方法:安装完整的vi $ sudo apt-get instal ...
- Spring MVC 中急速集成 Shiro 实践
相信有很多的程序员,不愿意进行用户管理这块代码实现. 原因之一,不同的JavaEE 系统,用户管理都会有个性化的实现,逻辑很繁琐. 而且是系统门面,以后背锅的几率非常大,可谓是低收益高风险. 最近在系 ...
- ajax请求,返回值为304 Not Modified 错误原因与解决办法
先说原因吧,这是因为http请求的缓存问题引起的 前后调用了两个相同的请求,服务器懒得给你重新发一个请求,所以就304咯 那怎么办呢? 解决方法也很简单,加一个时间戳就行了 比如: 原请求为: $.g ...
- 编程算法 - 迷宫的最短路径 代码(C++)
迷宫的最短路径 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定一个大小为N*M的迷宫. 迷宫由通道和墙壁组成, 每一步能够向邻接的上下 ...
- 【原创+亲测可用】JS如何区分微信浏览器、QQ浏览器和QQ内置浏览器
1.原理: 通过不同移动端的ua弹窗 获取user-agent 参数包含的信息,进行判断浏览器类型 在Android上 QQ内置环境的ua中有关键字 MQQBrowser, 并且后面包含一个[空白符+ ...
- 【php】(转载)分享一个好用的php违禁词 处理类
1.直接上代码: <?php //定义编码 header( 'Content-Type:text/html;charset=utf-8 '); $words=array('我','你','他') ...
- 邮件相关协议及JavaMail 包简介
1. 邮件服务器 按功能划分,邮件服务器可以划分为两种类型: SMTP邮件服务器:用于替用户发送邮件和接收外面发送给本地用户的邮件,相当于现实生活中邮局的邮件接收部门(可接收普通用户要投出的邮件和其他 ...
- Axure快速原型教程02--创建页面和设置界面
目录 Axure快速原型教程02--创建页面和设置界面 Axure快速原型教程01--原型说明下载和安装 首先,在左侧的面板中,我们发现有一个叫sitemap的面板,这个面板就是我们的一个个的页面了, ...
- ext4文件系统的delalloc选项造成单次写延迟增加的分析
最近我们的服务进程遇到kill -15后处于Z的状态,变为了僵尸进程,经过/proc/{thread_id}/stack查看其上线程的栈,发现是卡在了fwrite的过程中,而我们的系统中所有文件系统挂 ...
- 神奇的 Block
本文不做Block的基本介绍和底层实现原理,有兴趣的同学直接戳这篇文章(http://www.jianshu.com/p/51d04b7639f1),写得灰常好,本文只在应用层面上带领读者进行思考,并 ...