通过 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;
- }
- }
- }
- View Code
- 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);
- }
- }
- }
- View Code
入口
- 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());
- }
- }
- View Code
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 #>
- <#
- } #>
- View Code
自定义参数
- [Serializable]
- public class testType
- {
- public string Name { get; set; }
- }
- View Code
来源: https://www.cnblogs.com/zzfstudy/p/9796816.html