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. LintCode: Single Number

    C++ (1)异或操作 3^3=0 (2)for (auto &i : Obejuct) {} class Solution { public: /** * @param A: Array o ...

  2. Hierarchical query-层次查询之START WITH CONNECT BY用法

    Hierarchical query-层次查询中start with...connect by prior子句用法: connect by 是结构化查询中用到的,其基本语法是:  select ... ...

  3. REP report开发技巧

    其他文章 报表开发介绍 posted @ 2017-02-23 18:525 by Mark

  4. SqlDataAdapter概述

    SqlDataAdapter是 DataSet和 SQL Server之间的桥接器,用于检索和保存数据.SqlDataAdapter通过对数据源使用适当的Transact-SQL语句映射 Fill(它 ...

  5. 通过淘宝接口免费获取IP地址信息

    1.获取互联网访问IP信息 一般获取互联网访问的IP的相关信息一般都是收费接口,免费的接口不多,我使用到一个接口如下: http://ip.taobao.com/service/getIpInfo.p ...

  6. Java并发容器之CopyOnWriteArraySet与ConcurrentSkipListSet

    一:CopyOnWriteArraySet CopyOnWriteArraySet底层其实是通过CopyOnWriteArrayList来实现的,通过组合一个CopyOnWriteArrayList作 ...

  7. 【Windows】XShell中使用小键盘和ALT键(作Meta键),使BackSpace正常

    小键盘: 打开终端的Session属性,VT模式,初始数字键盘模式,设置为普通 ALT键: 打开终端的Session属性,元(Meta)键仿真,将ALT用作Meta键 BackSpace: 打开终端的 ...

  8. python之模块配置文件ConfigParser(在python3中变化较大)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之模块ConfigParser(在python3中为configparser) #特别注意:py ...

  9. 有关windows Gateway Ipsec 和NAT 兼容性问题

    1.简单通信拓扑: 将Windows 平台 作为一个网关,同一时候开启IPsec 和NAT来支持private和public的通信. 注意:IPSEC Gateway  和 Client1 Ipsec ...

  10. iteye-Spring的缺点有哪些

    http://www.iteye.com/topic/1126929 1. flounders --  发表时间:2012-09-25    如题,希望大侠们指出,不能用Spring就觉得他什么都好, ...