T4簡介
T4(Text Template Transformation Toolkit)在 Visual Studio 中,“T4 文本模板”是由一些文本塊和控制邏輯組成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制邏輯編寫為程序代碼的片段。生成的文件可以是任何類型的文本,例如網(wǎng)頁、資源文件或任何語言的程序源代碼。
T4 文本模板有兩種類型:
1、運(yùn)行時(shí)模板
可在應(yīng)用程序中執(zhí)行運(yùn)行時(shí) T4 文本模板(“預(yù)處理過的”模板)以便生成文本字符串(通常作為其輸出的一部分)。
若要?jiǎng)?chuàng)建運(yùn)行時(shí)模板,請向您的項(xiàng)目中添加“已預(yù)處理的文本模板”文件。
另外,您還可以添加純文本文件并將其“自定義工具”屬性設(shè)置為“TextTemplatingFilePreprocessor”。
2、設(shè)計(jì)時(shí)模板
在 Visual Studio 中執(zhí)行設(shè)計(jì)時(shí) T4 文本模板,以便定義應(yīng)用程序的部分源代碼和其他資源。
通常,您可以使用讀取單個(gè)輸入文件或數(shù)據(jù)庫中的數(shù)據(jù)的多個(gè)模板,并生成一些 .cs、.vb 或其他源文件。
每個(gè)模板都生成一個(gè)文件。 在 Visual Studio 或 MSBuild 內(nèi)執(zhí)行它們。
若要?jiǎng)?chuàng)建設(shè)計(jì)時(shí)模板,請向您的項(xiàng)目中添加“文本模板”文件。 另外,您還可以添加純文本文件并將其“自定義工具”屬性設(shè)置為“TextTemplatingFileGenerator”。
通過T4模板生成代碼,運(yùn)行時(shí)實(shí)現(xiàn)
關(guān)鍵代碼段: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> /// 文件擴(kuò)展名 /// </summary> public string FileExtension { get ; set ; } /// <summary> /// 文件擴(kuò)展名 /// </summary> public Encoding FileEncoding { get ; set ; } /// <summary> /// 錯(cuò)誤信息 /// </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> /// 參數(shù)傳遞 /// </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; //設(shè)置輸出文件的編碼格式 host.SetOutputEncoding(System.Text.Encoding.UTF8, false ); //通過Session將參數(shù)傳遞到模板 EngineHost.TextTemplatingSession keyValuePairs = new EngineHost.TextTemplatingSession(); testType t = new testType() { Name = "666666666666" }; keyValuePairs.Add( "test" , t); host.Session = keyValuePairs; //模板 string input = File.ReadAllText(templateFileName); //執(zhí)行代碼生成 string output = engine.ProcessTemplate(input, host); //設(shè)置文件的輸出路徑和文件擴(kuò)展名 ,,根據(jù)模板中的設(shè)置定義 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 #> <# } #> |
自定義參數(shù)
1
2
3
4
5
|
[Serializable] public class testType { public string Name { get ; set ; } } |
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。
原文鏈接:https://www.cnblogs.com/zzfstudy/p/9796816.html