首页 > 学院 > 开发设计 > 正文

用T4 Template生成代码

2019-11-17 03:02:40
字体:
来源:转载
供稿:网友

用T4 Template生成代码

2014-07-15 20:43 by Mike.Jiang, ... 阅读, ... 评论, 收藏, 编辑

1   T4语法

T4的语法与asp.net的方式比较类似。主要包括指令、文本块、控制块。

1.1 指令

指令主要包括template, output, assembly, import, include等类型,用以告诉T4引擎如何编译和运行一个模板。这些指令相当于T4引擎的配置参数。

示例:

<#@ template debug="true" hostspecific="true" language="C#"  #>

告诉T4引擎控制块用c#编写;

<#@ output extension=".cs" #>

告诉T4引擎生成文件的后缀名是.cs;

<#@ assembly name="System.Core"#>

告诉T4引擎编译运行时引用System.Core程序集;

<#@ assembly name="$(SolutionDir)/PRoject.CodeGenerator/bin/Debug/MySQL.Data.Dll"  #>

告诉T4引擎引用一个特定的位置上的程序集;

<#@ import namespace="System.Data.SqlClient"#>

告诉T4引擎编译运行时引用某个名称空间

<#@ include file="../Code/DBSchema.ttinclude"#>

告诉T4引擎编译运行时引用某个文件,类似于JS的引用

1.2 文本块

文本块, T4引擎会将文本块的内容直接复制到输出文件中。

1.3 控制块

控制块,主要用于控制文本的输出。在控制块可以写任意的C#代码。

1.4 示例Hello world

<#@ template debug="true" hostspecific="true" language="C#" #><#@ output extension=".txt" #>Hello, <#Write("World");#>

2   工作原理

转载自:http://www.olegsych.com/2007/12/text-template-transformation-toolkit/

1> Step1:编译模板,根据指令编译模板中的文本块和控制块,并生成一个继承于TextTransformation的类。

2> Step2: T4引擎动态创建类的实例,并调用TransformText方法。

3  在T4中读取表结构

我们用T4时,主要是基于数据库或配置文件来生成各类的代码。所以如何有效地获取数据库的结构信息,是比较重要的。 之前看很多人直接把获取数据库的信息放在每一个模板中,在更换其它数据库时,又要重写模板。一个模板同时支持多个项目时,不同的项目数据库很有可能是不同的。

主要设计思想如下,简单地应用了简单工厂模式。通过DBSchemaFactory类根据不同数据库类型,获取数据库访问类的接口IDBSchema。最后返回相同的表结构信息。

DBSchema.ttinclude类:

根据不同的数据库,获取表结构信息。已包括SQLSERVER和MYSQL。

<#@ assembly name="System.Core"#><#@ assembly name="System.Data" #><#@ assembly name="System.xml" #><#@ assembly name="$(SolutionDir)/bin/Debug/MySql.Data.Dll"  #><#@ import namespace="System"#><#@ import namespace="System.Collections.Generic"#><#@ import namespace="System.Data"#><#@ import namespace="System.Data.SqlClient"#><#@ import namespace="MySql.Data.MySqlClient"#><#+ #region Code    public class DBSchemaFactory    {        static readonly string DatabaseType = "SqlServer";        public static IDBSchema GetDBSchema()        {            IDBSchema dbSchema;            switch (DatabaseType)             {                case "SqlServer":                    {                        dbSchema =new SqlServerSchema();                        break;                    }                case "MySql":                    {                        dbSchema = new MySqlSchema();                        break;                    }                default:                     {                        throw new ArgumentException("The input argument of DatabaseType is invalid!");                    }            }            return dbSchema;        }    }    public interface IDBSchema : IDisposable    {        List<string> GetTablesList();        Table GetTableMetadata(string tableName);    }    public class SqlServerSchema : IDBSchema    {        public string ConnectionString = "Data Source=.;Initial Catalog=ProjectData;Persist Security Info=True;User ID=sa;PassWord=123456;";        public SqlConnection conn;        public SqlServerSchema()        {            conn = new SqlConnection(ConnectionString);            conn.Open();        }        public List<string> GetTablesList()        {            DataTable dt = conn.GetSchema("Tables");            List<string> list = new List<string>();            foreach (DataRow row in dt.Rows)            {                list.Add(row["TABLE_NAME"].ToString());            }            return list;        }        public Table GetTableMetadata(string tableName)        {            string selectCmdText = string.Format("SELECT * FROM {0}", tableName); ;            SqlCommand command = new SqlCommand(selectCmdText, conn);            SqlDataAdapter ad = new SqlDataAdapter(command);            System.Data.DataSet ds = new DataSet();            ad.FillSchema(ds, SchemaType.Mapped, tableName);            Table table = new Table(ds.Tables[0]);            return table;        }        public void Dispose()        {            if (conn != null)                conn.Close();        }    }    public class MySqlSchema : IDBSchema    {        public string ConnectionString = "Server=localhost;Port=3306;Database=ProjectData;Uid=root;Pwd=;";        public MySqlConnection conn;        public MySqlSchema()        {            conn = new MySqlConnection(ConnectionString);            conn.Open();        }        public List<string> GetTablesList()        {            DataTable dt = conn.GetSchema("Tables");            List<string> list = new List<string>();            foreach (DataRow row in dt.Rows)            {                list.Add(row["TABLE_NAME"].ToString());            }            return list;        }        public Table GetTableMetadata(string tableName)        {            string selectCmdText = string.Format("SELECT * FROM {0}", tableName); ;            MySqlCommand command = new MySqlCommand(selectCmdText, conn);            MySqlDataAdapter ad = new MySqlDataAdapter(command);            System.Data.DataSet ds = new DataSet();            ad.FillSchema(ds, SchemaType.Mapped, tableName);            Table table = new Table(ds.Tables[0]);            return table;        }        public void Dispose()        {            if (conn != null)                conn.Close();        }    }    public class Table    {        public Table(DataTable t)        {            this.PKs = this.GetPKList(t);            this.Columns = this.GetColumnList(t);            this.ColumnTypeNames = this.SetColumnNames();        }        public List<Column> PKs;        public List<Column> Columns;        public string ColumnTypeNames;        public List<Column> GetPKList(DataTable dt)        {            List<Column> list = new List<Column>();            Column c = null;            if (dt.PrimaryKey.Length > 0)            {                list = new List<Column>();                foreach (DataColumn dc in dt.PrimaryKey)                {                    c = new Column(dc);                    list.Add(c);                }            }            return list;        }        private List<Column> GetColumnList(DataTable dt)        {            List<Column> list = new List<Column>();            Column c = null;            foreach (DataColumn dc in dt.Columns)            {                c = new Column(dc);                list.Add(c);            }            return list;        }        private string SetColumnNames()        {            List<string> list = new List<string>();            foreach (Column c in this.Columns)            {                list.Add(string.Format("{0} {1}", c.TypeName, c.LowerColumnName));            }            return string.Join(",", list.ToArray());        }    }    public class Column    {        DataColumn columnBase;        public Column(DataColumn columnBase)        {            this.columnBase = columnBase;        }        public string ColumnName { get { return this.columnBase.ColumnName; } }        public string MaxLength { get { return this.columnBase.MaxLength.ToString(); } }        public string TypeName {             get             {                string result = string.Empty
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表