2014-01-12 124 views
1

我已經達到了我的應用程序開發中令人困惑的部分。使用T4模板ENum的

我正在使用自定義屬性進行身份驗證,名爲「Allowed For」,然後使用用戶類型。

例如,通過方法將有數據註解[Allowfor(UserType.Admin)]但我遇到的問題是,我想在數據庫中存儲UserTypes其下述性能的列表:

  • 編號
  • 刪除
  • 名稱
  • 說明

所以在運行時,甚至在按鈕的點擊我想建立一個Enum類,它擁有未被刪除的枚舉的列表。

任何人都可以擺動一些建議我的方式關於這一點,因爲我似乎無法做到這一點,我的自我,無法找到很多幫助谷歌搜索。

我只需要知道以下幾點:

  • 如何使用T4模板或類似的東西在VS創建一個類2013
  • 如何得到它該在每次構建的啓動/或者我在UI
  • 任何數據庫查找最好使用web配置文件中的字符串或使用的DbContext按下一個按鈕(EF如果可能的話)

回答

1

我已經做了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, 
    } 
} 

順便說一句,這是一個標籤(<#,<#=,<#+)之外的一切都將被髮送作爲班級的輸出。您需要確保您的模板在運行時正確設置,否則您可能因缺少括號而導致編譯錯誤等。