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");#>
转载自:http://www.olegsych.com/2007/12/text-template-transformation-toolkit/
1> Step1:编译模板,根据指令编译模板中的文本块和控制块,并生成一个继承于TextTransformation的类。
2> Step2: T4引擎动态创建类的实例,并调用TransformText方法。
我们用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
新闻热点
疑难解答