温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C#通过T4自动生成代码的案例

发布时间:2021-02-07 10:55:14 来源:亿速云 阅读:654 作者:小新 栏目:编程语言

小编给大家分享一下C#通过T4自动生成代码的案例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

T4简介

T4(Text Template Transformation Toolkit)在 Visual Studio 中,“T4 文本模板”是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段。生成的文件可以是任何类型的文本,例如网页、资源文件或任何语言的程序源代码。

T4 文本模板有两种类型:

1、运行时模板

可在应用程序中执行运行时 T4 文本模板(“预处理过的”模板)以便生成文本字符串(通常作为其输出的一部分)。

若要创建运行时模板,请向您的项目中添加“已预处理的文本模板”文件。

另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFilePreprocessor”。

2、设计时模板

在 Visual Studio 中执行设计时 T4 文本模板,以便定义应用程序的部分源代码和其他资源。

通常,您可以使用读取单个输入文件或数据库中的数据的多个模板,并生成一些 .cs、.vb 或其他源文件。

每个模板都生成一个文件。 在 Visual Studio 或 MSBuild 内执行它们。

若要创建设计时模板,请向您的项目中添加“文本模板”文件。 另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFileGenerator”。

通过T4模板生成代码,运行时实现

关键代码段:Host

using Microsoft.VisualStudio.TextTemplating; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeGenerate.EngineHost {  public class TextTemplatingEngineHost : ITextTemplatingEngineHost, ITextTemplatingSessionHost  {  public List<string> LocalDlls { get; set; }  public List<string> Namespaces { get; set; }  /// <summary>  /// 模板文件  /// </summary>  public string TemplateFile { get; set; }  /// <summary>  /// 文件扩展名  /// </summary>  public string FileExtension { get; set; }  /// <summary>  /// 文件扩展名  /// </summary>  public Encoding FileEncoding { get; set; }  /// <summary>  /// 错误信息  /// </summary>  public CompilerErrorCollection Errors { get; set; }  public IList<string> StandardAssemblyReferences  {   get   {   LocalDlls.Add(typeof(System.Uri).Assembly.Location);   return LocalDlls;   }  }  public IList<string> StandardImports  {   get   {   Namespaces.Add("System");   return Namespaces;   }  }  /// <summary>  /// 参数传递  /// </summary>  public ITextTemplatingSession Session { get; set; }  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)  {   FileExtension = extension;  }  public void SetOutputEncoding(System.Text.Encoding encoding, bool fromOutputDirective)  {   FileEncoding = encoding;  }  public void LogErrors(CompilerErrorCollection errors)  {   Errors = errors;  }  public AppDomain ProvideTemplatingAppDomain(string content)  {   return AppDomain.CreateDomain("Generation App Domain");  }  public ITextTemplatingSession CreateSession()  {   return this.Session;  }  } }

Session

using Microsoft.VisualStudio.TextTemplating; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace CodeGenerate.EngineHost {  [Serializable]  public class TextTemplatingSession : Dictionary<string, Object>, ITextTemplatingSession, ISerializable  {   public Guid Id { get;private set; }   public TextTemplatingSession() : this(Guid.NewGuid())   {   }   public TextTemplatingSession(Guid id)   {    this.Id = id;   }   public override int GetHashCode()   {    return Id.GetHashCode();   }   public TextTemplatingSession(SerializationInfo info, StreamingContext context)    : base(info, context)   {    Id = (Guid)info.GetValue("Id", typeof(Guid));   }   void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)   {    base.GetObjectData(info, context);    info.AddValue("Id", Id);   }   public override bool Equals(object obj)   {    var o = obj as TextTemplatingSession;    return o != null && o.Equals(this);   }   public bool Equals(ITextTemplatingSession other)   {    return other != null && other.Id == this.Id;   }   public bool Equals(Guid other)   {    return other.Equals(Id);   }  } }

入口

string templateFileName = "Template/test.tt";    TextTemplatingEngineHost host = new TextTemplatingEngineHost();    Engine engine = new Engine();    //引入本地dll    host.LocalDlls = new List<string>() { AppDomain.CurrentDomain.BaseDirectory.ToString() + "Params.dll" };    //引入命名空间    host.Namespaces = new List<string>() { "Params" };    //模板文件    host.TemplateFile = templateFileName;    //设置输出文件的编码格式    host.SetOutputEncoding(System.Text.Encoding.UTF8, false);    //通过Session将参数传递到模板    EngineHost.TextTemplatingSession keyValuePairs = new EngineHost.TextTemplatingSession();    testType t = new testType() { Name = "666666666666" };    keyValuePairs.Add("test", t);    host.Session = keyValuePairs;    //模板    string input = File.ReadAllText(templateFileName);    //执行代码生成    string output = engine.ProcessTemplate(input, host);    //设置文件的输出路径和文件扩展名 ,,根据模板中的设置定义    string outputFileName = string.Concat(     AppDomain.CurrentDomain.BaseDirectory.ToString(), "Output/",     Path.GetFileNameWithoutExtension(templateFileName),     host.FileExtension);    //将生成的文件写入到新位置    File.WriteAllText(outputFileName, output, host.FileEncoding);    if (host.Errors.HasErrors)    {     foreach (CompilerError error in host.Errors)     {      MessageBox.Show(error.ToString());     }    }

tt文件

<#@ template debug="false" hostspecific="false" language="C#" #> <#@ import namespace="System.Collections.Generic" #> <#@ assembly name="Params.dll" #> <#@ import namespace="Params" #> <#@ parameter type="Params.testType" name="test" #> <#@ output extension=".cs" #> <# if(test!=null&&test.Name!=null){#> <#=test.Name #> <# } #>

自定义参数

[Serializable]  public class testType  {   public string Name { get; set; }  }

以上是“C#通过T4自动生成代码的案例”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

t4
AI