饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 41 页

作者:Nick Randolph/等 当前章节:15398 字 更新时间:2026-6-18 14:51

generated fi le this shouldn ’ t be an issue.

Creating a T4 Template . 265

266 .

chaPter 14 code generATion WiTh T4

At the bottom of the template file add a single line containing the words Hello World and save the

template.

c#

<#@ template debug="false" hostspecific="false" language="C#" #>

<#@ output extension=".txt" #>

Hello World

Code snippet HelloWorld.tt

Vb

<#@ template debug="false" hostspecific="false" language="VB" #>

<#@ output extension=".txt" #>

Hello World

Code snippet HelloWorld.tt

As was mentioned previously, templates are run every time they are saved, so the generated file will

be updated with the new contents of the template. Open up the generated file and you will see the

text Hello World in there.

Although each individual template file can always be regenerated by

opening it and saving it again, Visual Studio also has a button at the top

of the Solution Explorer tool window to Transform All Templates (see

fiGure 14-4

Figure 14-4). Clicking this button transforms all of the templates in the

solution.

As was mentioned previously, if the output directive specifies an extension that matches the

language of the current project, the resulting generated file is included in the project. You will get

full IntelliSense from types and members declared within generated files. The next code snippet

shows a T4 template along with the code that it generates. The generated class can be accessed by

other parts of the program and a small console application demonstrating this follows.

c#

<#@ template debug="false" hostspecific="false" language="C#" #>

<#@ output extension=".cs" #>

namespace AdventureWorks {

class GreetingManager {

public static void SayHi() {

System.Console.WriteLine("Aloha Cousin!");

}

}

}

Code snippet GreetingManager.tt

namespace AdventureWorks {

class GreetingManager {

public static void SayHi() {

Creating a T4 Template .

267

System.Console.WriteLine("Aloha Cousin!");

}

}

}

Code snippet GreetingManager.cs

namespace AdventureWorks {

class Program {

static void Main(string[] args) {

GreetingManager.SayHi();

}

}

}

Code snippet Program.cs

Vb

< #@ template debug="false" hostspecific="false" language="VB" # >

< #@ output extension=".vb" # >

Public Class GreetingManager

Public Shared Sub SayHi

System.Console.WriteLine( "Aloha Cousin!" )

End Sub

End Class

Code snippet GreetingManager.tt

Public Class GreetingManager

Public Shared Sub SayHi()

System.Console.WriteLine("Aloha Cousin!")

End Sub

End Class

Code snippet GreetingManager.vb

Module Module1

Sub Main()

GreetingManager.SayHi()

End Sub

End Module

Code snippet Module1.vb

Although the rest of your application will get IntelliSense covering your

generated code, the T4 template files themselves have no IntelliSense or syntax

highlighting in Visual Studio 2010. A few third-party editors and plug-ins are

available that provide a richer design-time experience for T4.

268 .

chaPter 14 code generATion WiTh T4

This example works, but it doesn’t really demonstrate the power and flexibility that T4 can offer.

This is because the template is completely static. To create useful templates, more dynamic capabilities

are required.

t4 buildinG blocks

Each T4 template consists of a number of blocks which affect the generated file. The line

Hello World from the first example is a Text block. Text blocks are copied verbatim from the

template file into the generated file. They can contain any kind of text and can contain other blocks.

In addition to Text blocks, three other types of blocks exist: Expression blocks, Statement blocks,

and Class Feature blocks. Each of the other types of block is surrounded by a specific kind of

markup to identify it. Text blocks are the only type of block that have no special markup.

expression blocks

An Expression block is used to pass some computed value to the generated file. Expression blocks

normally appear inside of Text blocks and are denoted by <#= and #> tags. Here is an example of a

template that outputs the date and time that the file was generated.

c#

<#@ template debug="false" hostspecific="false" language="C#" #>

<#@ output extension=".txt" #>

This file was generated: <#=System.DateTime.Now #>

Code snippet Existential.tt

Vb

<#@ template debug="false" hostspecific="false" language="VB" #>

<#@ output extension=".txt" #>

This file was generated: <#=System.DateTime.Now #>

Code snippet Existential.tt

The expression inside the block may be any valid expression in the template language that is

specified in the template directive. Every time it is run the template evaluates the expression and

then calls ToString() on the result. This value is then inserted into the generated file.

statement blocks

A Statement block is used to execute arbitrary statements when the template is run. Code inside a

Statement block might log the execution of the template, create temporary variables, or delete a file

from your computer, so you need to be careful. In fact, the code inside a Statement block can consist

of any valid statement in the template language. Statement blocks are commonly used to implement

flow control within a template, manage temporary variables, and interact with other systems. A

Statement block is denoted by <# and #> tags which are similar to Statement block delimiters but

without the equals sign. The following example produces a file with all 99 verses of a popular

drinking song.

T4 Building Blocks .

269

c#

< #@ template debug="false" hostspecific="false" language="C#" # >

< #@ output extension=".txt" # >

< # for( int i = 99; i > = 1; i-- )

{ # >

< #=i # > Bottles of Non-alcoholic Carbonated Beverage on the wall

< #=i # > Bottles of Non-alcoholic Carbonated Beverage

Take one down

And pass it around

< # if( i-1 == 0 ) { # >

There's no Bottles of Non-alcoholic Carbonated Beverage on the wall

< # } else { # >

There's < #=i-1 # > Bottles of Non-alcoholic Carbonated Beverage on the wall

< # } # >

< # } # >

Code snippet DrinkingSong.tt

Vb

< #@ template debug="false" hostspecific="false" language="VB" # >

< #@ output extension=".txt" # >

< # For i As Integer = 99 To 1 Step -1 # >

< #= i # > Bottles of Non-alcoholic Carbonated Beverage on the wall

< #= i # > Bottles of Non-alcoholic Carbonated Beverage

Take one down

And pass it around

< # If i - 1 = 0 Then # >

There's no Bottles of Non-Alcoholic Carbonated Beverage on the wall.

< # Else # >

There's < #= i-1 # > Bottles of Non-alcoholic Carbonated Beverage on the wall.

< # End If # >

< # Next # >

Code snippet DrinkingSong.tt

In the preceding example the Statement block contains another Text block,

which in turn contains a number of Expression blocks. Using these three block

types alone enables you to create some very powerful templates.

Although the Statement block in the example contains other blocks, it doesn’t need to. From within

a Statement block you can write directly to the generated file using the Write() and WriteLine()

methods. Here is the example again using this method.

c#

< #@ template debug=”false” hostspecific=”false” language=”C#” #>

<#@ output extension=”.txt” #>

<#

270 .

chaPter 14 code generATion WiTh T4

for( int i = 99; i > 1; i-- )

{

WriteLine( “{0} Bottles of Non-alcoholic Carbonated Beverage on the wall”, i);

WriteLine( “{0} Bottles of Non-alcoholic Carbonated Beverage”, i );

WriteLine( “Take one down” );

WriteLine( “And pass it around” );

if( i - 1 == 0 ) {

WriteLine(

“There’s no Bottles of Non-alcoholic Carbonated Beverage on the wall.” );

} else {

WriteLine(

“There’s {0} Bottles of Non-alcoholic Carbonated Beverage on the wall.”,i-1);

}

WriteLine( “” );

} #>

Code snippet ImperativeDrinkingSong.tt

Vb

<#@ template debug=”false” hostspecific=”false” language=”VB” #>

<#@ output extension=”.txt” #>

<# For i As Integer = 99 To 1 Step -1

Me.WriteLine(“{0} Bottles of Non-alcoholic Carbonated Beverage on the wall”, i)

Me.WriteLine(“{0} Bottles of Non-alcoholic Carbonated Beverage”, i)

Me.WriteLine(“Take one down”)

Me.WriteLine(“And pass it around”)

If i - 1 = 0 Then

WriteLine(“There’s no Bottles of Non-Alcoholic Carbonated Beverage on the” &_

“ wall.”)

Else

WriteLine(“There’s {0} Bottles of Non-alcoholic Carbonated Beverage on the” &_

“ wall.”,i-1)

End If

Me.WriteLine( “” )

Next #>

Code snippet ImperativeDrinkingSong.tt

The final generated results for these two templates are the same. Depending on the template, you

might find one technique or the other easier to understand. It is recommended that you use one

technique exclusively in each template to avoid confusion.

class feature blocks

The final type of T4 block is the Class Feature block. These blocks contain arbitrary code that can

be called from Statement and Expression blocks to help in the production of the generated file. This

often includes custom formatting code or repetitive tasks. Class Feature blocks are denoted using

<#+ and #> tags which are similar to those that denote Expression blocks except that the equals sign

in the opening tag becomes a plus character. The following template writes the numbers from –5

T4 Building Blocks .

271

to 5 using a typical financial format where every number has two decimal places, is preceded by a

dollar symbol, and negatives are written as positive amounts but are placed in brackets.

c#

<#@ template debug=”false” hostspecific=”false” language=”C#” #>

<#@ output extension=”.txt” #>

Financial Sample Data

<# for( int i = -5; i <= 5; i++ )

{

WriteFinancialNumber(i);

WriteLine( “” );

} #>

End of Sample Data

<#+

void WriteFinancialNumber(decimal amount)

{

if( amount < 0 )

Write(“(${0:#0.00})”, System.Math.Abs(amount) );

else

Write(“${0:#0.00}”, amount);

}

#>

Code snippet FinancialData.tt

Vb

<#@ template debug=”true” hostspecific=”false” language=”VB” #>

<#@ output extension=”.txt” #>

Financial Sample Data

<# For i as Integer = -5 To 5

WriteFinancialNumber(i)

WriteLine( “” )

Next #>

End of Sample Data

<#+

Sub WriteFinancialNumber(amount as Decimal)

If amount < 0 Then

Write(“(${0:#0.00})”, System.Math.Abs(amount) )

Else

Write(“${0:#0.00}”, amount)

End If

End Sub

#>

Code snippet FinancialData.tt

Class Feature blocks can contain Text blocks and Expression blocks but they cannot contain

Statement blocks. In addition to this, no Statement blocks are allowed to appear once the first Class

Feature block is encountered.

272 .

chaPter 14 code generATion WiTh T4

Now that you know the four different types of T4 blocks that can appear within a template file, it’s

time to see how Visual Studio 2010 is able to use them to generate the output file.

how t4 works

The process of generating a file from a T4 template comprises two basic steps. In the first step,

the .tt file is used to generate a standard .NET class. This class inherits from the abstract

(MustInherit) Microsoft.VisualStudio.TextTemplating.TextTransformation class and

overrides a method called TransformText().

In the second step, an instance of this class is created and configured, and the TransformText

method is called. This method returns a string that is used as the contents of the generated file.

Normally, you won’t see the generated class file but you can configure the T4 engine to make a copy

available by turning debugging on for the template. This simply involves setting the debug attribute

of the template directive to true and saving the template file.

After a T4 template is executed in Debug mode a number of files are created in the temporary folder

of the system. One of these files will have a random name and a .cs or a .vb extension (depending

on the template language). This file contains the actual generator class.

You can find the temporary folder of the system by opening a Visual Studio

command prompt and entering the command echo %TEMP%.

This code contains a lot of pre-processor directives that support template debugging but

make the code quite difficult to read. Here are the contents of the code file generated from the

FinancialSample.tt template presented in the previous section reformatted and with these

directives removed.

C#

namespace Microsoft.VisualStudio.TextTemplatingBE7601CBE8A6858147D586FD8FC4C6F9

{

using System;

public class GeneratedTextTransformation :

Microsoft.VisualStudio.TextTemplating.TextTransformation

{

public override string TransformText()

{

try

{

this.Write("\r\nFinancial Sample Data\r\n");

for( int i = -5; i < = 5; i++ )

{

WriteFinancialNumber(i);

WriteLine( "" );

}

this.Write("End of Sample Data\r\n\r\n ");

How T4 Works .

273

}

catch (System.Exception e)

{

System.CodeDom.Compiler.CompilerError error = new~CA

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页