T4簡介
T4(Text Template Transformation Toolkit)在 Visual Studio 中,“T4 文本模板”是由一些文本塊和控制邏輯組成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制邏輯編寫為程序代碼的片段。生成的文件可以是任何類型的文本,例如網頁、資源文件或任何語言的程序源代碼。
T4 文本模板有兩種類型:
1、運行時模板
可在應用程序中執行運行時 T4 文本模板(“預處理過的”模板)以便生成文本字符串(通常作為其輸出的一部分)。
若要創建運行時模板,請向您的項目中添加“已預處理的文本模板”文件。
另外,您還可以添加純文本文件并將其“自定義工具”屬性設置為“TextTemplatingFilePreprocessor”。
2、設計時模板
在 Visual Studio 中執行設計時 T4 文本模板,以便定義應用程序的部分源代碼和其他資源。
通常,您可以使用讀取單個輸入文件或數據庫中的數據的多個模板,并生成一些 .cs、.vb 或其他源文件。
每個模板都生成一個文件。 在 Visual Studio 或 MSBuild 內執行它們。
若要創建設計時模板,請向您的項目中添加“文本模板”文件。 另外,您還可以添加純文本文件并將其“自定義工具”屬性設置為“TextTemplatingFileGenerator”。
通過T4模板生成代碼,運行時實現
關鍵代碼段:Host
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
using Microsoft.VisualStudio.TextTemplating; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeGenerate.EngineHost { public class TextTemplatingEngineHost : ITextTemplatingEngineHost, ITextTemplatingSessionHost { public List< string > LocalDlls { get ; set ; } public List< string > Namespaces { get ; set ; } /// <summary> /// 模板文件 /// </summary> public string TemplateFile { get ; set ; } /// <summary> /// 文件擴展名 /// </summary> public string FileExtension { get ; set ; } /// <summary> /// 文件擴展名 /// </summary> public Encoding FileEncoding { get ; set ; } /// <summary> /// 錯誤信息 /// </summary> public CompilerErrorCollection Errors { get ; set ; } public IList< string > StandardAssemblyReferences { get { LocalDlls.Add( typeof (System.Uri).Assembly.Location); return LocalDlls; } } public IList< string > StandardImports { get { Namespaces.Add( "System" ); return Namespaces; } } /// <summary> /// 參數傳遞 /// </summary> public ITextTemplatingSession Session { get ; set ; } public bool LoadIncludeText( string requestFileName, out string content, out string location) { content = System.String.Empty; location = System.String.Empty; if (File.Exists(requestFileName)) { content = File.ReadAllText(requestFileName); return true ; } else { return false ; } } public object GetHostOption( string optionName) { object returnObject; switch (optionName) { case "CacheAssemblies" : returnObject = true ; break ; default : returnObject = null ; break ; } return returnObject; } public string ResolveAssemblyReference( string assemblyReference) { if (File.Exists(assemblyReference)) { return assemblyReference; } string candidate = Path.Combine(Path.GetDirectoryName( this .TemplateFile), assemblyReference); if (File.Exists(candidate)) { return candidate; } return "" ; } public Type ResolveDirectiveProcessor( string processorName) { if ( string .Compare(processorName, "XYZ" , StringComparison.OrdinalIgnoreCase) == 0) { //return typeof(); } throw new Exception( "Directive Processor not found" ); } public string ResolvePath( string fileName) { if (fileName == null ) { throw new ArgumentNullException( "the file name cannot be null" ); } if (File.Exists(fileName)) { return fileName; } string candidate = Path.Combine(Path.GetDirectoryName( this .TemplateFile), fileName); if (File.Exists(candidate)) { return candidate; } return fileName; } public string ResolveParameterValue( string directiveId, string processorName, string parameterName) { if (directiveId == null ) { throw new ArgumentNullException( "the directiveId cannot be null" ); } if (processorName == null ) { throw new ArgumentNullException( "the processorName cannot be null" ); } if (parameterName == null ) { throw new ArgumentNullException( "the parameterName cannot be null" ); } return String.Empty; } public void SetFileExtension( string extension) { FileExtension = extension; } public void SetOutputEncoding(System.Text.Encoding encoding, bool fromOutputDirective) { FileEncoding = encoding; } public void LogErrors(CompilerErrorCollection errors) { Errors = errors; } public AppDomain ProvideTemplatingAppDomain( string content) { return AppDomain.CreateDomain( "Generation App Domain" ); } public ITextTemplatingSession CreateSession() { return this .Session; } } } |
Session
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
using Microsoft.VisualStudio.TextTemplating; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace CodeGenerate.EngineHost { [Serializable] public class TextTemplatingSession : Dictionary< string , Object>, ITextTemplatingSession, ISerializable { public Guid Id { get ; private set ; } public TextTemplatingSession() : this (Guid.NewGuid()) { } public TextTemplatingSession(Guid id) { this .Id = id; } public override int GetHashCode() { return Id.GetHashCode(); } public TextTemplatingSession(SerializationInfo info, StreamingContext context) : base (info, context) { Id = (Guid)info.GetValue( "Id" , typeof (Guid)); } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { base .GetObjectData(info, context); info.AddValue( "Id" , Id); } public override bool Equals( object obj) { var o = obj as TextTemplatingSession; return o != null && o.Equals( this ); } public bool Equals(ITextTemplatingSession other) { return other != null && other.Id == this .Id; } public bool Equals(Guid other) { return other.Equals(Id); } } } |
入口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
string templateFileName = "Template/test.tt" ; TextTemplatingEngineHost host = new TextTemplatingEngineHost(); Engine engine = new Engine(); //引入本地dll host.LocalDlls = new List< string >() { AppDomain.CurrentDomain.BaseDirectory.ToString() + "Params.dll" }; //引入命名空間 host.Namespaces = new List< string >() { "Params" }; //模板文件 host.TemplateFile = templateFileName; //設置輸出文件的編碼格式 host.SetOutputEncoding(System.Text.Encoding.UTF8, false ); //通過Session將參數傳遞到模板 EngineHost.TextTemplatingSession keyValuePairs = new EngineHost.TextTemplatingSession(); testType t = new testType() { Name = "666666666666" }; keyValuePairs.Add( "test" , t); host.Session = keyValuePairs; //模板 string input = File.ReadAllText(templateFileName); //執行代碼生成 string output = engine.ProcessTemplate(input, host); //設置文件的輸出路徑和文件擴展名 ,,根據模板中的設置定義 string outputFileName = string .Concat( AppDomain.CurrentDomain.BaseDirectory.ToString(), "Output/" , Path.GetFileNameWithoutExtension(templateFileName), host.FileExtension); //將生成的文件寫入到新位置 File.WriteAllText(outputFileName, output, host.FileEncoding); if (host.Errors.HasErrors) { foreach (CompilerError error in host.Errors) { MessageBox.Show(error.ToString()); } } |
tt文件
1
2
3
4
5
6
7
8
9
|
<#@ template debug= "false" hostspecific= "false" language= "C#" #> <#@ import namespace = "System.Collections.Generic" #> <#@ assembly name= "Params.dll" #> <#@ import namespace = "Params" #> <#@ parameter type= "Params.testType" name= "test" #> <#@ output extension= ".cs" #> <# if (test!= null &&test.Name!= null ){#> <#=test.Name #> <# } #> |
自定義參數
1
2
3
4
5
|
[Serializable] public class testType { public string Name { get ; set ; } } |
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://www.cnblogs.com/zzfstudy/p/9796816.html