T4 Manager

发布时间 2023-09-21 09:56:01作者: valeb
<#@ assembly name="System.Core"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#+ 
    class Manager
    {
        public struct Block
        {
            public String Name;
            public int Start, Length;
        }

        public List<Block> blocks = new List<Block>();
        public Block currentBlock;
        public Block footerBlock = new Block();
        public Block headerBlock = new Block();
        public ITextTemplatingEngineHost host;
        public ManagementStrategy strategy;
        public StringBuilder template;
        public String OutputPath { get; set; }
        public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader)
        {
            this.host = host;
            this.template = template;
            OutputPath = String.Empty;
            strategy = ManagementStrategy.Create(host);
        }
        ///开始
        public void StartBlock(String name)
        {
            currentBlock = new Block { Name = name, Start = template.Length };
        }

        ///头部开始
        public void StartHeader()
        {
            headerBlock.Start = template.Length;
        }
        ///头部结束
        public void EndHeader()
        {
            headerBlock.Length = template.Length - headerBlock.Start;
        }
         
        ///底部开始
        public void StartFooter()
        {
            footerBlock.Start = template.Length;
        }
        ///底部结束
        public void EndFooter()
        {
            footerBlock.Length = template.Length - footerBlock.Start;
        }
     
        ///结束
        public void EndBlock()
        {
            currentBlock.Length = template.Length - currentBlock.Start;
            blocks.Add(currentBlock);
        }
        
        ///执行
        public void Process(bool split)
        {
            String header = template.ToString(headerBlock.Start, headerBlock.Length);
            String footer = template.ToString(footerBlock.Start, footerBlock.Length);
            blocks.Reverse();
            foreach (Block block in blocks)
            {
                String fileName = Path.Combine(OutputPath, block.Name);  
                if (split)
                {
                    String content = header + template.ToString(block.Start, block.Length) + footer;
                    strategy.CreateFile(fileName, content);
                    template.Remove(block.Start, block.Length);
                }
                else
                {
                    strategy.DeleteFile(fileName);
                }
            }
        }

        ///数据库类型转换成C#类型
        public string ToClrType(string dataType, bool isNullable)
        {
            string returnType = string.Empty;
            switch (dataType)
            { 
                case "BigInt":
                    returnType = string.Format("{0}{1}", "long", isNullable ? "?" : "");
                    break;
                case "Binary":
                case "Image":
                case "Timestamp":
                case "VarBinary": 
                case "Byte[]": 
                    returnType = "byte[]";
                    break;
                case "Bit":
                case "Boolean":
                    returnType = string.Format("{0}{1}", "bool", isNullable ? "?" : "");
                    break;
                case "Char":
                case "NChar":
                case "NText":
                case "NVarChar":
                case "Text":
                case "VarChar":
                case "Xml":
                case "String":
                    returnType = string.Format("{0}{1}", "string", "");
                    break;
                case "DateTime":
                case "SmallDateTime":
                case "Date":
                case "Time":
                case "DateTime2":
                    returnType = string.Format("{0}{1}", "System.DateTime", isNullable ? "?" : "");
                    break;
                case "Decimal":
                case "Money":
                case "SmallMoney":
                    returnType = string.Format("{0}{1}", "decimal", isNullable ? "?" : "");
                    break;
                case "Float":
                    returnType = string.Format("{0}{1}", "double", isNullable ? "?" : "");
                    break;
                case "Int":
                case "Int32": 
                case "Int64":
                    returnType = string.Format("{0}{1}", "int", isNullable ? "?" : "");
                    break; 
                case "Real":
                    returnType = string.Format("{0}{1}", "float", isNullable ? "?" : "");
                    break;
                case "UniqueIdentifier":
                    returnType = string.Format("{0}{1}", "Guid", isNullable ? "?" : "");
                    break;
                case "SmallInt":
                    returnType = string.Format("{0}{1}", "short", isNullable ? "?" : "");
                    break;
                case "TinyInt":
                    returnType = string.Format("{0}{1}", "byte", isNullable ? "?" : "");
                    break;
                case "Variant":
                    returnType = string.Format("{0}{1}", "object", "");
                    break;
                case "DateTimeOffset":
                    returnType = string.Format("{0}{1}", "DateTimeOffset", isNullable ? "?" : "");
                    break;
                default:
                    returnType = "string";
                    break;
            }

            return returnType;
        }
    }

    class ManagementStrategy
    {
        
        internal static ManagementStrategy Create(ITextTemplatingEngineHost host)
        {
            return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);
        }

        internal ManagementStrategy(ITextTemplatingEngineHost host) { }

        ///创建文件
        internal virtual void CreateFile(String fileName, String content)
        {
            File.WriteAllText(fileName, content);
        }
        ///删除文件
        internal virtual void DeleteFile(String fileName)
        {
            if (File.Exists(fileName))
                File.Delete(fileName);
        }
    }

    class VSManagementStrategy : ManagementStrategy
    {
        private EnvDTE.ProjectItem templateProjectItem;

        ///构造函数
        internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host)
        {
            IServiceProvider hostServiceProvider = (IServiceProvider)host;
            if (hostServiceProvider == null)
                throw new ArgumentNullException("Could not obtain hostServiceProvider");

            EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
            if (dte == null)
                throw new ArgumentNullException("Could not obtain DTE from host");

            templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
        }

        ///创建文件
        internal override void CreateFile(String fileName, String content)
        {
            base.CreateFile(fileName, content);
            ((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);
        }

        ///删除文件
        internal override void DeleteFile(String fileName)
        {
            ((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);
        }

        ///查找并删除文件
        private void FindAndDeleteFile(String fileName)
        {
            foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
            {
                if (projectItem.get_FileNames(0) == fileName)
                {
                    projectItem.Delete();
                    return;
                }
            }
        }
    }
#>