前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# 通过T4自动生成代码

C# 通过T4自动生成代码

作者头像
FreeTimeWorker
发布2020-08-31 13:28:54
6950
发布2020-08-31 13:28:54
举报
文章被收录于专栏:C#开发点点滴滴

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

关键代码段:Host

代码语言:javascript
复制
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

代码语言:javascript
复制
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);
        }
    }
}

入口

代码语言:javascript
复制
  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文件

代码语言:javascript
复制
<#@ 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 #>
<#    } #>

自定义参数

代码语言:javascript
复制
 [Serializable]
    public class testType
    {
        public string Name { get; set; }
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-10-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档