我已經做了T4模板非常相似的東西秒。技巧是知道需要哪些dll,找到它們等(例如,在Visual Studio 2013中,EnvDET被引用爲「import namespace =」EnvDTE「而不是EvnDTE.dll)
基本上你需要和他們一起玩嘗試並得到你想要的結果在你的解決方案中創建一個T4項目,然後開始填充它。
我使用命令對象(並且使用下面的代碼使用MySQL庫),但它應該給你一個想法怎麼我跑了。
<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".generated.cs" #>
<#@ Assembly Name="EnvDTE" #>
<#@ Assembly Name="System.Data" #>
<#@ Assembly Name="$(SolutionDir)Services.Entities\bin\DevTest\Libraries.DB.dll" #> **// * custom location for custom libraries**
<#@ Assembly Name="$(SolutionDir)Services.Entities\bin\DevTest\MySql.Data.dll" #> **// custom location for custom libraries**
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
string tableName = "";
//string path = Path.GetDirectoryName(Host.TemplateFile);
string connectionString = "mysqlConnectionString"; **// replaced with regular value, could pull from web.config but it's only updated rarely**
// Get containing project
IServiceProvider serviceProvider = (IServiceProvider)Host;
DTE dte = (DTE)serviceProvider.GetService(typeof(DTE));
//Project project = dte.Solution.FindProjectItem(Host.TemplateFile).ContainingProject;
#>
using System;
using System.CodeDom.Compiler;
namespace Services.Entities
{
[GeneratedCode("TextTemplatingFileGenerator", "10")]
public enum Store
{
<#
using (var cmd = new Libraries.DB.Mysql.Command(connectionString)) **//Custom libraries to open a disposable command object**
{
cmd.Clear();
cmd.AppendCmd("select id, storecode, StoreName \n");
cmd.AppendCmd("from stores \n");
var reader = cmd.ExecuteReader();
while(reader.Read())
{
int storeId = Convert.ToInt32(reader["id"]);
string storecode = reader["storecode"].ToString();
string description = reader["StoreName"].ToString();
#> //We now have the data, let's use it! The code in <#= gets populated #>**
[Libraries.Utils.Enums.Info(Code = "<#= storecode #>", Name = "<#= description #>")] <#= Sanitize(description) #> = <#= storeId #>,
<#
}
}
#>
}
}
//This is a method which takes a name like "Some Descripton" and Sanitizes it to Some_Description so it can be usable as an enum**
<#+
static string Sanitize(string token)
{
// Replace all invalid chars by underscores
token = Regex.Replace(token, @"[\W\b]", "_", RegexOptions.IgnoreCase);
// If it starts with a digit, prefix it with an underscore
token = Regex.Replace(token, @"^\d", @"_$0");
// Check for reserved words
// TODO: Clean this up and add other reserved words (keywords, etc)
if (token == "Url") token = "_Url";
return token;
}
#>
需要注意這些文件的關鍵問題是,之間< ##家居>是代碼即運行,並且您可以在該代碼中創建變量。顯示,很像ASP,<#=變量#>。
我不確定這些文件是否在您每次構建解決方案時自動構建,但似乎這將是一個簡單的構建腳本。要編輯它們,請在保存時進行編輯。您可以右鍵單擊該文件並從上下文菜單中單擊「運行自定義工具」。您將通過文件和相關的生成文件來查看錯誤,以檢查它。
順便說一句,上面可能會產生這樣的事情:
using System;
using System.CodeDom.Compiler;
namespace Services.Entities
{
[GeneratedCode("TextTemplatingFileGenerator", "10")]
public enum Store
{
[Libraries.Utils.Enums.Info(Code = "ST1", Name = "Store 1")] Store1 = 1,
[Libraries.Utils.Enums.Info(Code = "ST2", Name = "Store 2")] Store2 = 2,
}
}
順便說一句,這是一個標籤(<#,<#=,<#+)之外的一切都將被髮送作爲班級的輸出。您需要確保您的模板在運行時正確設置,否則您可能因缺少括號而導致編譯錯誤等。