zoukankan      html  css  js  c++  java
  • C# 通过T4自动生成代码

    通过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
  • 相关阅读:
    如何利用WGET覆写已存在的档案
    linux 脚本返回值
    ubuntu的配置网络
    非交互模式修改Ubuntu密码的命令
    [zz]python多进程编程
    [zz]linux修改密码出现Authentication token manipulation error的解决办法
    [zz]4.1.5 进程的处理器亲和性和vCPU的绑定
    vcpu
    非交互式调用交互式程序
    HDOJ_ACM_饭卡
  • 原文地址:https://www.cnblogs.com/zzfstudy/p/9796816.html
Copyright © 2011-2022 走看看