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文本模板转换过程,布布扣,bubuko.com

时间: 2024-10-27 12:29:22

T4文本模板转换过程的相关文章

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

说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了.今天痛定思痛,终于把这件拖了很久的事做了.好,不废话了,现在看看"一个简单的代码生成器" . 先看看界面吧! 简约到如此,说是代码生成器,估计是要被吐槽的.好吧,借用园子里博友的说法,这只是一粒粟子,如果你愿意,你能看到代码生成器的"种子". 这样运行的! 画了个简图已描述这个简单的代码生成器的工作过程.下面的介绍将以此图展开: 1)读取数据表的信息:从数据库中读取数据表的

编写 T4 文本模板

文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板处理方式的元素,为模板转换引擎提供说明. T4文本模板指令包括:    T4模板指令:  T4参数指令:  T4输出指令:  T4程序集指令:  T4导入指令:  T4包含指令:  T4 CleanUpBehavior 指令及其自定义指令. 指令的语法如下所示: <#@ DirectiveName

T4文本模板

<#...#> 可以包含语句 <#=...#>  用于表达式,提供“输出”操作 <#+ ...> 使用类功能控制块向文本模板添加方法.属性.字段,必须作为文件中最后一个块显示 assembly 指令使指定的程序集可供模板代码使用,方式与 Visual Studio 项目中的“引用”部分相同. 您无需包括对 System.dll 的引用,它是自动引用的. import 指令允许您使用类型而不使用其完全限定名,方式与普通程序文件中的 using 指令相同 若要从相对于文本模

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

转自:http://www.cnblogs.com/huangcong/archive/2011/07/20/1931107.html 在之前的文本模板(T4)初体验中我们已经知道了T4的用处,下面就看看如何用它来实现批量修改实体框架(Entity Framework)中的类名.我们都知道ADO.NET 实体数据模型中有一种方式是以数据库模型来生成数据模型的,这是个很简便的实体数据模型生成的方式,但是因为微软提供的自定义接口不足,我们无法实现对生成的数据模型实体类批量进行修改(至少我上网找了很久

T4模板之文本模板

网址:https://docs.microsoft.com/en-us/visualstudio/modeling/design-time-code-generation-by-using-t4-text-templates?view=vs-2017 T4模板在平时我们其实都会或多或少的遇到.最多的用在实体与数据库的映射上面. 这里只记录一下他的语法. 需要的插件:vs2017 T4代码高亮插件:Devart T4 Editor T4生成多文件:T4 Toolbox  (使用这个可以很好的生成我

关于C#中文本模板(.tt)的简单应用

转自http://www.it165.net/pro/html/201409/21789.html 这两天做项目突遇 .tt文件,之前没有接触过,so查询学习做笔记,帮助记忆和后来者. 在项目添加中点击选择文本模板 下面贴出代码,做了简单的注释 01.<#@ template debug="false" hostspecific="false" language="C#" #> 02.<#@ assembly name=&quo

JSON、文本模板、HTML模板

JSON JSON是一种发送和接收格式化信息的标准.JSON不是唯一的标准,XML.ASN.1 和 Google 的 Protocol Buffer 都是相似的标准.Go通过标准库 encoding/json.encoding/xml.encoding/asn1 和其他的库对这些格式的编码和解码提供了非常好的支持,这些库都拥有相同的API. 序列化输出 首先定义一组数据: type Movie struct { Title string Year int `json:"released"

T4模板之基础篇

一.回顾 上一篇文章 ——T4模板之菜菜鸟篇,我们囫囵吞枣的创建了与“T4模板”有关的文件.在创建各个文件的这一个过程中,我们对于T4模板有了那么丁点的认识.现在就带着之前的那些问题,正式的迈入对“T4模板”的学习. 二.概念 2.1.类型 T4 文本模板有两种类型: 设计时 T4 文本模板 运行时 T4 文本模板 三.简要教程 我们只讲“设计时T4文本模板”,其他的都TMD属于高级部分了,哥不懂给不给? 打开之前我们创建的“TextTemplate_.tt”文件: 很明显的有一个特征,那么就是

T4模板:T4模板之菜鸟篇

一.废话 T4(Text Template Transformation Toolkit)是微软官方在VisualStudio 2008中开始使用的代码生成引擎.在 Visual Studio 中,"T4 文本模板"是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件. 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段.生成的文件可以是任何类型的文本,例如网页.资源文件或任何语言的程序源代码.现在的VS中只要与代码生成相关的场景基本上都能找T