• T4文本模板转换过程


    T4文本模板转换过程将文本模板文件作为输入,生成一个新的文本文件作为输出。 例如,可以使用文本模板生成 Visual Basic 或 C# 代码,还可以生成 HTML 报告。

    有三个组件参与这一过程:引擎宿主指令处理器。 引擎对该过程进行控制(引擎与宿主和指令处理器交互),以生成输出文件;宿主提供与环境的所有交互(如定位文件和程序集); 指令处理器为文本模板添加功能(如从 XML 文件或数据库读取数据等)。

    组件:

    组件 说明 可自定义(是/否)
    引擎 引擎组件控制文本模板转换过程。
    主机 宿主是引擎与用户环境之间的接口。 Visual Studio 是文本转换过程的宿主。 是。 可以编写自定义宿主。
    指令处理器 指令处理器是处理文本模板中的指令的类。 可以使用指令从输入源向文本模板提供数据。 是。 可以编写自定义指令处理器。

    引擎:

    引擎以字符串形式从宿主接收模板,而宿主处理在转换过程中所用的所有文件。 接下来,引擎请求宿主定位所有自定义指令处理器和环境中的其他方面。 然后,引擎编译和运行生成转换类。 引擎将生成的文本返回给宿主,宿主通常将该文本保存到文件中。

    宿主:

    宿主负责转换过程之外与环境有关的所有操作,包括:

    1)查找引擎或指令处理器请求的文本和二进制文件。 宿主可以搜索目录和全局程序集缓存以查找程序集。 宿主可以为引擎查找自定义指令处理器代码。 宿主还可以查找并读取文本文件,然后以字符串形式返回其内容。

    2)提供标准程序集和命名空间的列表,供引擎用于创建生成转换类。

    3)提供引擎在编译和执行生成转换类时所用的应用程序域。 将使用独立应用程序域,以免宿主应用程序受到模板代码错误的影响。

    4)写入生成的输出文件。

    5)设置生成的输出文件的默认扩展名。

    6)处理文本模板转换错误。 例如,宿主可以将错误显示在用户界面中,也可以将错误写入文件。 (在 Visual Studio 中,错误显示在“错误消息”窗口中。)

    7)在用户调用了指令但未提供值时,提供必需的参数值。 指令处理器可以指定指令名称和参数,可以请求宿主提供默认值(如果有)。

    指令和指令处理器:

    指令是文本模板中的命令。 它向生成过程提供参数。 通常,指令定义模型或其他输入的源和类型,以及输出文件的文件扩展名等。

    指令处理器可以处理一个或多个指令。 转换模板之前,必须安装能够处理模板中的指令的指令处理器。


    有了基本的概念,我们看下面的Demo(在程序中动态执行T4模板):


    在程序中动态执行T4模板:

    执行结果:

    image

    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 #>
  • 相关阅读:
    iframe透明
    c#创建可以为空类型
    div仿框架布局
    IBatis.Net学习笔记(六):Castle.DynamicProxy的使用
    很好玩的谷歌纵横
    TFS签入签出规范
    ibatis学习笔记
    iBATIS.net调用存储过程
    最新28个很棒的 jQuery 教程
    IBatis.Net 中的数据类型转换
  • 原文地址:https://www.cnblogs.com/hanzhaoxin/p/3790165.html
Copyright © 2020-2023  润新知