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文本模板转换过程的更多相关文章

  1. 一个简单的代码生成器(T4文本模板运用)

    说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了.今天痛定思痛,终于把这件拖了很久的事做了.好,不废话了,现在看看"一个简单的代码生成器" ...

  2. 编写 T4 文本模板

    文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板 ...

  3. T4 文本模板编写准则

    如果要在 Visual Studio 中生成程序代码或其他应用程序资源,遵守以下一般准则可能非常有帮助. 它们并不是一成不变的规则. 设计时 T4 模板准则 设计时 T4 模板是在设计时在 Visua ...

  4. 使用 T4 文本模板生成设计时代码

      使用设计时 T4 文本模板,您可以在 Visual Studio 项目中生成程序代码和其他文件. 通常,您编写一些模板,以便它们根据来自模型的数据来改变所生成的代码. 模型是包含有关应用程序要求的 ...

  5. T4文本模板

    <#...#> 可以包含语句 <#=...#>  用于表达式,提供“输出”操作 <#+ ...> 使用类功能控制块向文本模板添加方法.属性.字段,必须作为文件中最后 ...

  6. MVC开发T4代码生成之一----文本模板基础

    T4文本模板 T4全写为Text Template Transformation Toolkit,是一种编程辅助工具,用来使程序代码自(懒)动(猿)生(福)成(利)的工具.MVC开发中大量使用了T4模 ...

  7. C#代码生成工具:文本模板初体验 使用T4批量修改实体框架(Entity Framework)的类名

    转自:http://www.cnblogs.com/huangcong/archive/2011/07/20/1931107.html 在之前的文本模板(T4)初体验中我们已经知道了T4的用处,下面就 ...

  8. T4((Text Template Transformation Toolkit))模版引擎之基础入门 C#中文本模板(.tt)的应用

    1 关于C#中文本模板(.tt)的简单应用https://blog.csdn.net/zunguitiancheng/article/details/78011145 任何一个傻瓜都能写出计算机能理解 ...

  9. T4模板之文本模板

    网址:https://docs.microsoft.com/en-us/visualstudio/modeling/design-time-code-generation-by-using-t4-te ...

随机推荐

  1. 【linux】ubuntu中上下左右键变为^[[A^[[B^[[D^[[C问题处理

    问题现象: 使用上下左右键时,结果为 ^[[A^[[B^[[D^[[C,如图: 原因在于ubuntu系统自带的 vi 不完整导致. 解决方法:安装完整的vi $ sudo apt-get instal ...

  2. Spring MVC 中急速集成 Shiro 实践

    相信有很多的程序员,不愿意进行用户管理这块代码实现. 原因之一,不同的JavaEE 系统,用户管理都会有个性化的实现,逻辑很繁琐. 而且是系统门面,以后背锅的几率非常大,可谓是低收益高风险. 最近在系 ...

  3. ajax请求,返回值为304 Not Modified 错误原因与解决办法

    先说原因吧,这是因为http请求的缓存问题引起的 前后调用了两个相同的请求,服务器懒得给你重新发一个请求,所以就304咯 那怎么办呢? 解决方法也很简单,加一个时间戳就行了 比如: 原请求为: $.g ...

  4. 编程算法 - 迷宫的最短路径 代码(C++)

    迷宫的最短路径 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定一个大小为N*M的迷宫. 迷宫由通道和墙壁组成, 每一步能够向邻接的上下 ...

  5. 【原创+亲测可用】JS如何区分微信浏览器、QQ浏览器和QQ内置浏览器

    1.原理: 通过不同移动端的ua弹窗 获取user-agent 参数包含的信息,进行判断浏览器类型 在Android上 QQ内置环境的ua中有关键字 MQQBrowser, 并且后面包含一个[空白符+ ...

  6. 【php】(转载)分享一个好用的php违禁词 处理类

    1.直接上代码: <?php //定义编码 header( 'Content-Type:text/html;charset=utf-8 '); $words=array('我','你','他') ...

  7. 邮件相关协议及JavaMail 包简介

    1. 邮件服务器 按功能划分,邮件服务器可以划分为两种类型: SMTP邮件服务器:用于替用户发送邮件和接收外面发送给本地用户的邮件,相当于现实生活中邮局的邮件接收部门(可接收普通用户要投出的邮件和其他 ...

  8. Axure快速原型教程02--创建页面和设置界面

    目录 Axure快速原型教程02--创建页面和设置界面 Axure快速原型教程01--原型说明下载和安装 首先,在左侧的面板中,我们发现有一个叫sitemap的面板,这个面板就是我们的一个个的页面了, ...

  9. ext4文件系统的delalloc选项造成单次写延迟增加的分析

    最近我们的服务进程遇到kill -15后处于Z的状态,变为了僵尸进程,经过/proc/{thread_id}/stack查看其上线程的栈,发现是卡在了fwrite的过程中,而我们的系统中所有文件系统挂 ...

  10. 神奇的 Block

    本文不做Block的基本介绍和底层实现原理,有兴趣的同学直接戳这篇文章(http://www.jianshu.com/p/51d04b7639f1),写得灰常好,本文只在应用层面上带领读者进行思考,并 ...