您好,登錄后才能下訂單哦!
小編給大家分享一下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自動生成代碼的案例”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。