Csharp/C#教程:C#如何通过T4自动生成代码详解分享

T4简介

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

T4文本模板有两种类型:

1、运行时模板

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

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

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

2、设计时模板

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

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

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

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

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

关键代码段:Host

usingMicrosoft.VisualStudio.TextTemplating; usingSystem; usingSystem.CodeDom.Compiler; usingSystem.Collections.Generic; usingSystem.IO; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; namespaceCodeGenerate.EngineHost { publicclassTextTemplatingEngineHost:ITextTemplatingEngineHost,ITextTemplatingSessionHost { publicList<string>LocalDlls{get;set;} publicList<string>Namespaces{get;set;} ///<summary> ///模板文件 ///</summary> publicstringTemplateFile{get;set;} ///<summary> ///文件扩展名 ///</summary> publicstringFileExtension{get;set;} ///<summary> ///文件扩展名 ///</summary> publicEncodingFileEncoding{get;set;} ///<summary> ///错误信息 ///</summary> publicCompilerErrorCollectionErrors{get;set;} publicIList<string>StandardAssemblyReferences { get { LocalDlls.Add(typeof(System.Uri).Assembly.Location); returnLocalDlls; } } publicIList<string>StandardImports { get { Namespaces.Add("System"); returnNamespaces; } } ///<summary> ///参数传递 ///</summary> publicITextTemplatingSessionSession{get;set;} publicboolLoadIncludeText(stringrequestFileName,outstringcontent,outstringlocation) { content=System.String.Empty; location=System.String.Empty; if(File.Exists(requestFileName)) { content=File.ReadAllText(requestFileName); returntrue; } else { returnfalse; } } publicobjectGetHostOption(stringoptionName) { objectreturnObject; switch(optionName) { case"CacheAssemblies": returnObject=true; break; default: returnObject=null; break; } returnreturnObject; } publicstringResolveAssemblyReference(stringassemblyReference) { if(File.Exists(assemblyReference)) { returnassemblyReference; } stringcandidate=Path.Combine(Path.GetDirectoryName(this.TemplateFile),assemblyReference); if(File.Exists(candidate)) { returncandidate; } return""; } publicTypeResolveDirectiveProcessor(stringprocessorName) { if(string.Compare(processorName,"XYZ",StringComparison.OrdinalIgnoreCase)==0) { //returntypeof(); } thrownewException("DirectiveProcessornotfound"); } publicstringResolvePath(stringfileName) { if(fileName==null) { thrownewArgumentNullException("thefilenamecannotbenull"); } if(File.Exists(fileName)) { returnfileName; } stringcandidate=Path.Combine(Path.GetDirectoryName(this.TemplateFile),fileName); if(File.Exists(candidate)) { returncandidate; } returnfileName; } publicstringResolveParameterValue(stringdirectiveId,stringprocessorName,stringparameterName) { if(directiveId==null) { thrownewArgumentNullException("thedirectiveIdcannotbenull"); } if(processorName==null) { thrownewArgumentNullException("theprocessorNamecannotbenull"); } if(parameterName==null) { thrownewArgumentNullException("theparameterNamecannotbenull"); } returnString.Empty; } publicvoidSetFileExtension(stringextension) { FileExtension=extension; } publicvoidSetOutputEncoding(System.Text.Encodingencoding,boolfromOutputDirective) { FileEncoding=encoding; } publicvoidLogErrors(CompilerErrorCollectionerrors) { Errors=errors; } publicAppDomainProvideTemplatingAppDomain(stringcontent) { returnAppDomain.CreateDomain("GenerationAppDomain"); } publicITextTemplatingSessionCreateSession() { returnthis.Session; } } }

Session

usingMicrosoft.VisualStudio.TextTemplating; usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Runtime.Serialization; usingSystem.Text; usingSystem.Threading.Tasks; namespaceCodeGenerate.EngineHost { [Serializable] publicclassTextTemplatingSession:Dictionary<string,Object>,ITextTemplatingSession,ISerializable { publicGuidId{get;privateset;} publicTextTemplatingSession():this(Guid.NewGuid()) { } publicTextTemplatingSession(Guidid) { this.Id=id; } publicoverrideintGetHashCode() { returnId.GetHashCode(); } publicTextTemplatingSession(SerializationInfoinfo,StreamingContextcontext) :base(info,context) { Id=(Guid)info.GetValue("Id",typeof(Guid)); } voidISerializable.GetObjectData(SerializationInfoinfo,StreamingContextcontext) { base.GetObjectData(info,context); info.AddValue("Id",Id); } publicoverrideboolEquals(objectobj) { varo=objasTextTemplatingSession; returno!=null&&o.Equals(this); } publicboolEquals(ITextTemplatingSessionother) { returnother!=null&&other.Id==this.Id; } publicboolEquals(Guidother) { returnother.Equals(Id); } } }

入口

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

tt文件

<#@templatedebug="false"hostspecific="false"language="C#"#> <#@importnamespace="System.Collections.Generic"#> <#@assemblyname="Params.dll"#> <#@importnamespace="Params"#> <#@parametertype="Params.testType"name="test"#> <#@outputextension=".cs"#> <#if(test!=null&&test.Name!=null){#> <#=test.Name#> <#}#>

自定义参数

[Serializable] publicclasstestType { publicstringName{get;set;} }

上述就是C#学习教程:C#如何通过T4自动生成代码详解分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/908289.html

(0)
上一篇 2021年10月25日
下一篇 2021年10月25日

精彩推荐