文字範本(T4) - 透過資料表產生 enum 的內容 ( 改為引用外部 dll 方式)

改為引用外部 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

如果有其他情況,就自行變通吧