C#如何通過T4自動生成代碼詳解
T4簡介
T4(Text Template Transformation Toolkit)在 Visual Studio 中,“T4 文本模板”是由一些文本塊和控制邏輯組成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制邏輯編寫為程序代碼的片段。生成的文件可以是任何類型的文本,例如網(wǎng)頁、資源文件或任何語言的程序源代碼。
T4 文本模板有兩種類型:
1、運行時模板
可在應(yīng)用程序中執(zhí)行運行時 T4 文本模板(“預(yù)處理過的”模板)以便生成文本字符串(通常作為其輸出的一部分)。
若要創(chuàng)建運行時模板,請向您的項目中添加“已預(yù)處理的文本模板”文件。
另外,您還可以添加純文本文件并將其“自定義工具”屬性設(shè)置為“TextTemplatingFilePreprocessor”。
2、設(shè)計時模板
在 Visual Studio 中執(zhí)行設(shè)計時 T4 文本模板,以便定義應(yīng)用程序的部分源代碼和其他資源。
通常,您可以使用讀取單個輸入文件或數(shù)據(jù)庫中的數(shù)據(jù)的多個模板,并生成一些 .cs、.vb 或其他源文件。
每個模板都生成一個文件。 在 Visual Studio 或 MSBuild 內(nèi)執(zhí)行它們。
若要創(chuàng)建設(shè)計時模板,請向您的項目中添加“文本模板”文件。 另外,您還可以添加純文本文件并將其“自定義工具”屬性設(shè)置為“TextTemplatingFileGenerator”。
通過T4模板生成代碼,運行時實現(xiàn)
關(guān)鍵代碼段: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> /// 參數(shù)傳遞 /// </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; //設(shè)置輸出文件的編碼格式 host.SetOutputEncoding(System.Text.Encoding.UTF8, false); //通過Session將參數(shù)傳遞到模板 EngineHost.TextTemplatingSession keyValuePairs = new EngineHost.TextTemplatingSession(); testType t = new testType() { Name = "666666666666" }; keyValuePairs.Add("test", t); host.Session = keyValuePairs; //模板 string input = File.ReadAllText(templateFileName); //執(zhí)行代碼生成 string output = engine.ProcessTemplate(input, host); //設(shè)置文件的輸出路徑和文件擴展名 ,,根據(jù)模板中的設(shè)置定義 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 #> <# } #>
自定義參數(shù)
[Serializable] public class testType { public string Name { get; set; } }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對我們的支持。
欄 目:C#教程
下一篇:Win10下C# DateTime出現(xiàn)星期幾問題的解決方法
本文標題:C#如何通過T4自動生成代碼詳解
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5050.html
您可能感興趣的文章
- 01-10C#通過反射獲取當前工程中所有窗體并打開的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的方法
- 01-10Extjs4如何處理后臺json數(shù)據(jù)中日期和時間
- 01-10C#通過Semaphore類控制線程隊列的方法
- 01-10asp.net中XML如何做增刪改查操作
- 01-10C#.NET中如何批量插入大量數(shù)據(jù)到數(shù)據(jù)庫中
- 01-10C#通過正則表達式實現(xiàn)提取網(wǎng)頁中的圖片
- 01-10解析C#中的常量及如何在C#編程中定義常量
- 01-10如何使用C#從word文檔中提取圖片
- 01-10c#檢測文本文件編碼的方法


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10delphi制作wav文件的方法
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10C#中split用法實例總結(jié)
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置