改為引用外部 dll 的方式是為了:
1.減少在 T4 內輸入錯誤語法並修正的時間
2.也可以減少 T4 引用太多 dll & 指定太多 namespace
首先,專案結構改為下圖這個方式,跟建立 DAL 的觀念一樣
EnumGenerator.cs 裡面用來放產生 enum 內容 method 的地方
EnumCategory.tt 就是 T4 的檔案
EnumGenerator.cs 的內容如下:
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
namespace Data
{
public class EnumGenerator
{
public string getEnumText(string table)
{
List<string> enumText = new List<string>();
string result = "";
using (SqlConnection conn = new SqlConnection())
{
string sql = @"SELECT * FROM @table WHERE CategoryID < @cid";
conn.ConnectionString = @"Data Source =.\mssql2014; Initial Catalog = Northwind; Integrated Security = True";
conn.Open();
sql = sql.Replace("@table", table);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@cid", 10);
SqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
foreach (DataRow row in dt.Rows)
{
enumText.Add($"{removeSign(row["CategoryName"].ToString())}={row["CategoryID"]}");
}
}
result = string.Join(",\r\n", enumText);
return result;
}
private static string removeSign(string str)
{
str = str.Replace(" ", "");
str = str.Replace("/", "");
return str;
}
}
}
EnumCategory.tt 的內容如下:
<#@ template language="C#" debug="True" hostspecific="True" #>
<#@ output extension=".cs" #>
<#@ assembly name="$(SolutionDir)\Data\bin\Debug\Data.dll" #>
<#@ import namespace="Data" #>
<#
string table = "Categories";
EnumGenerator eg = new EnumGenerator();
string result = eg.getEnumText(table);
#>
using System;
namespace Data
{
public enum <#=table#>
{
<#= result #>
}
}
產生的內容如下:
最後來比較一下 T4 前後的內容差異:
原本的寫法:
後來的寫法:
最後,強調一點:
因為 tt 跟 類別庫 dll 放在 同個專案內
所以必須先寫完成類別庫的 dll 的建立,再撰寫 tt
如果有其他情況,就自行變通吧