最近由于需要在框架中提供一些自定义模板的功能,找到了一篇博客,可惜似乎是翻译工具直接翻的,读不通顺,就试着自己翻译下,我不会完全翻译原文的句子,可能会对原文进行小范围的我认为更合适的句子并添加些注释,,原文地址如下:

http://blogs.msdn.com/b/webdev/archive/2009/01/29/t4-templates-a-quick-start-guide-for-asp-net-mvc-developers.aspx

  在我们最近的博客中提到的ASP.NET MVC Release Candidate中,我们使用了T4 (Text Template Transformation Toolkit)模板来实现了Add Controller和Add View的代码自动生成功能。我们希望能使用T4给大家带来开发速度上的提升,因为用户可以在很大程度上定制这些模板。

模板的位置和重写

  Add Controller和Add View都是通过在后台执行T4模板来实现代码自动生成的。通过一些工具可以修改模板来定制想要生成的代码。默认模板的位置在: [Visual Studio Install Directory]\Common7\IDE\ItemTemplates\[CSharp | VisualBasic]\Web\MVC\CodeTemplates\

  你也可以把“CodeTemplates”目录复制到项目的根目录以便作为每一个项目的基础在上述位置重写和定制模板(只需要创建目录名为“CodeTemplates”的目录,并在其下创建“AddController”和“AddView”的子目录即可)。需要默认目录下有一些模板的重写可能不起作用,因为自动生成代码时将会优先选取项目目录中匹配的模板。还有一个重点需要注意,你可以为Add View功能增加自己的.tt 文件,无论是在公用目录下还是独立的项目中,添加后都可以自动的显示在Add View窗口的视图选择的下拉框中。

另外,复制上述文件夹(添加.tt文件)到项目中时,都会有警告提示,如下图:

(运行这些文本模板可能会对你的电脑产生危害。如果模板来源不可信请不要运行。)

点击“Cancel”将不能使用T4模板(如果你复制“CodeTemplates”目录并增加多个.tt文件时,你都选择了“Cancel”)。因为一旦项目发现一个.tt文件,文件的“自定义工具(CustomTool①)”属性将被设置成“TextTemplatingFileGeneraror”,它会通知Visual Studio使用默认的T4宿主(Host②)去执行这个模板并且创建一个基于此模板内容的新的文件(在模板所在的目录)。

①      :自定义工具是一个实现了 Visual Studio 定义的IVsSingleFileGenerator接口的特殊组件。T4 自定义工具由Microsoft.VisualStudio.TextTemplating.VSHost.TemplatedCodeGenerator类实现并且在注册表中注册在Visual Studio 下命名为TextTemplatingFileGenerator。Visual Studio 将使用该名称查找自定义工具、创建 COM 对象并调用其IVsSingleFileGenerator.Generate方法

②      :Microsoft.VisualStudio.TextTemplating.VSHost.10.0.dll 的TextTemplatingService服务实现Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost接口,为代码生成引擎提供 Host (宿主)。在模板转换过程中: Engine 负责代码生成;Host负责提供转换过程中行为具体实现及所需要的的所有外部资源,ITextTemplatingEngineHost和模板内容一起传递到Engine.ProcessTempalte方法中用于代码生成

  

  对于基于模板的一次性文件生成或简单的使用T4,生成器都可以作为好的的实现方式---但是,因为依赖于自定义模板的宿主的Add View 和Add Controller模板都包含代码(后面会提到),使用默认的生成器执行模板将会生成错误。需要复制模板到项目中之后然后清空自定义工具属性值。

注意:如果你想去掉复制.tt文件时自动设置自定义工具的映射值,你可以通过注册表实现---注意如果你想要恢复注册表为默认值,你可以执行Visual Studio的恢复安装,或手动改回。启动注册表编辑器并且找到指定的目录(根据你的机器选择是32位还是64位):

32:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators

64位:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\Generators

展开“Generators”下第一层的每一个节点并找到“.tt”。设置“(Default)”项的值为空,就可以了。

如果你想重写全局模板,并且不想复制“CodeTemplates”目录到你的项目(大概是你已经有了个同名目录),你可以通过注册表修改Add Controller Add View默认的目录名。启动注册表编辑器并且找到指定的目录(根据你的机器选择是32位还是64位):

32-bit: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\MVC\CodeTemplates

64-bit: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\MVC\CodeTemplates

改变“OverrideDir”项的值为你想要T4工具检索的目录名。需要注意的是,新设置的目录下依然需要保证与原来相同的目录结构,即包含“AddController”和“AddView”目录。

编辑T4模板

如果你使用Visual Studio打开一个.tt文件,你可能会发现它的内容没有层次---平铺在上面。我们强烈推荐你使用T4编辑器,一个Clarius Consulting开发的Visual Studio插件,它可以在你编辑模板时提供语法高亮和一些基本的T4语句的自动完成。有免费的“Community Edition”,以及更强大的“Professional Edition”---如果你有兴趣可以比较下不同的特性。下面你将会看到,这个插件真的让模板制作有了很大不同。

深入剖析T4模板

  最简单的学习编辑自定义模板的方法是先看默认模板如何工作。为此,我们通过一些Add View的模板来了解“Create”(创建.tt文件)。现在从头开始:

  这四行代码都是指令。

  1.第一行是模板指令,它的主要作用是通知T4引擎,模板使用哪种语言编写。这里所说的模板使用的语言并不是模板会输出这种语言,而这种语言会控制模板的输出(例如,模板中可能会报刊一个 if-else语句用来控制哪些文本被输出)。在使用Add View 或者Add Controller之时,“HostSpecific”属性需要设置为“True”,否则模板将不能访问Add View 和Add Controller功能提供的信息(比如将类型绑定为View的强类型,等等)。

  2.紧接着的是输出指令,它简单的通过通知模板宿主来设置模板输出文件的扩展名---这不是MVC特有的工具,因为根据不同情况可能会忽略默认的扩展名(例如,如果我们依赖partial view ,扩展名应该是.ascx)。

  3.接下来的两行都是引用指令,C#中通常使用“using”,VB中使用“Imports”。如果你在模板中使用了用它们所写的代码,你需要在这个位置引用它们。

  你可以在这里找到更多T4指令的文档:http://msdn.microsoft.com/en-us/library/bb126421.aspx

  下面一点,注意一下后面的这行:

  这行我们新建了一个变量“mvcHost”,将“Host”转换类型并赋值给它。因为我们指令中设置了“HostSpecific”属性为“True”,“Host”被自动提供给模板。MVC工具提供了一个自定义宿主,以便能将信息传递给只有工具内部可访问的模板。为了访问我们的宿主类中提供的这些属性,“Host”必须转换为我们自定义的宿主类型“MvcTextTemplateHost”。

这个变量的使用实际上非常简单:

  首先需要注意的是,‘<#’ 和 ‘#>’标签之间包含有一些的代码。这两个标签用来调用语句块和包含控制代码。你的模板可能要有条件的输出文本块到输出文件中,同时保持其他文本块的正常输出。上面,我们有一个if语句(使用C#,因为模板的语言使用模板指令设置成了C#),使用了“{”。这个if语句的“}”出现在后面一些行中的的第17行,在不同的语句块中。注意,这里的这个if语句访问了宿主的“IsViewUserControl”属性,这个属性的作用是通知模板用户选择的是否是partial view。

  模板中所有这些标记之外的文本块都会直接输出到实际的文件中。在上面的截图中,第14行的文本在标记块之外,因此会直接输出---尽管如此,它只会在12行的if语句值判断为“true”的情况下才会输出到文件中。

  你可以在这里了解到更多关于T4语句块的信息:http://msdn.microsoft.com/en-us/library/bb126509.aspx

  理解T4模板中控制代码的最简单的方法是在大脑中将它连接为一个完整的程序。我们之前在第6行声明的变量可以被之后的T4控制代码使用---之后每一个if-else分支条件都可以使用这个变量并且添加一些文本(灰色的)到输出的文件中。上面的If-else语句选择一些由模板宿主提供的属性传递给Add View模板。

  后面一些行中有一个奇怪的语句块:

  我们声明了一个“List<string>”类型的变量。我们怎么能在T4代码中使用List类型的?因为可以看到我们在模板顶部的引用指令:

  第56行调用了一个方法“FilterProperties”---但是方法在哪?实际上这个方法的定义在模板底部:

  如果你仔细看,这个语句块有点不一样,是以“<#+”开始的。这是一个用来表示类的块,它们这样工作:T4模板带有所有的类的特征,并且将这些特征添加到在模板的后台编译的类中。这不只限于方法,还包括属性(通常包含在类中的)。像一个正规代码文件中的类成员一样,它们可以被模板中的其他代码访问。

  关于类特征块的更多信息:http://msdn.microsoft.com/en-us/library/bb126541.aspx

  我们的默认模板使用上面截图中的“FilterProperties”方法在默认输出中的type包含的标记过滤获得一些properties,这些标记必须是公共的和像GirdView一样可以在设计器中显示的。这与调用GridView .IsBindableType方法的结果在逻辑上是相同的。

(这段翻译的很别扭,所以附上原文,请大家帮忙指正)

  Our default templates use the ‘FilterProperties’ method from the above screenshot to by default output markup only for some properties in the type – namely ones that are public and would also be displayed in the designer by things like GridView.  This logic is identical to what you would get from calling the GridView.IsBindableType method.

  在136行调用的“IsBindableType”是在模板后面一点位置被定义的:

  如果你想改变我们模板过滤掉的某个属性,你可以按照你的喜好修改任意一个方法。

  最后,看看第65行:

  这里有一个新的标记开头“<#=”。它被一个表达式块调用并且用来插入T4代码的值到输出文本。像你在上面看到的,我们有一个foreach循环,迭代properties 并定义一个局部变量来循环调用“propertyName”。我们使用表达式块引用该变量,因为我们想为每一个属性名输出一个<th>标签。

  更多关于表达式块:http://msdn.microsoft.com/en-us/library/bb126508.aspx

  如你所见,上面各种使用T4模板的方法通过选择性的输出文本使T4成为一个强大的工具,帮助我们获得灵活的自定义的自动代码生成。

MVC工具的T4宿主属性

  Add Controller 和Add View功能都通过模板宿主提供不同的属性给模板,上述说明贯穿了创建模板的过程。这里完整的列出了模板宿主的有效属性,供你的模板使用(注意:这些属性的实际名称可能会因为不同的版本有所不同)。

Add Controller:

Property Name

Type

Description

ItemName

System.String

带有“Controller”后缀的Controller类的名称

NameSpace

System.String

生成的Controller类的命名空间

ExtraActionMethods

System.Boolean

指示用户是否选择在Add Controller窗口中扩展Action方法

ControllerRootName

System.String

不带“Controller’”后缀的Controller类的名称

Add View:

Property Name

Type

Description

ItemName

System.String

不带扩展名的View名称,例如显示于Add View窗口中的

NameSpace

System.String

默认以View所在的目录作为命名空间

IsViewUserControl

System.Boolean

在Add View窗口中用户是否选择了partial view

IsViewContentPage

System.Boolean

用户创建View时是否带有master page

IsViewPage

System.Boolean

用户创建的是否是符合规范的视图页

MasterPage

System.String

用户在窗口中选择的master page路径 (只能在 IsViewContentPage是true的时候使用)

ContentPlaceholder

System.String

生成内容所在位置的占位符名称。是用户输入到Add View 窗口中内容占位符ID

ContentPlaceHolders

System.Collections.Generic.List<System.String>

master page中所有内容占位符ID的列表, 如果View选择了master page

LanguageExtension

System.String

输出文件的扩展名 (包含”.”)

ViewDataTypeGenericString

System.String

在View指令中用来输出泛型”Inherits”属性的字符串(强类型 view).  例如: “<MyType>” 或 “(Of MyType)”

ViewDataType

System.Type

被绑定的强类型View的Type对象。可以获得类型的属性信息等

  此外,你会发现一些提供给宿主的用用的属性,比如正在执行的模板路径。更多关于这些属性: http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.texttemplating.itexttemplatingenginehost_properties.aspx

摘要

  我们希望这篇文章带给了你足够关于T4模板的信息,能帮你有效的结合Visual Web Developer provides for ASP.NET MVC工具。你如果想知道这篇博客之外更多的信息,可以看看那的信息(Scott Hanselman’s博客不错)并看看你能得到什么。请回复您的评论,建议或问题。谢谢您的阅读!

T4 模板 : 一种提升ASP.NET MVC开发速度方法的更多相关文章

  1. ASP.Net MVC开发基础学习笔记:一、走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  2. ASP.Net MVC开发基础学习笔记(1):走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  3. ASP.NET MVC开发:Web项目开发必备知识点

    最近加班加点完成一个Web项目,使用Asp.net MVC开发.很久以前接触的Asp.net开发还是Aspx形式,什么Razor引擎,什么MVC还是这次开发才明白,可以算是新手. 对新手而言,那进行A ...

  4. 解析ASP.NET Mvc开发之删除修改数据

    目录: 1)从明源动力到创新工场这一路走来 2)解析ASP.NET WebForm和Mvc开发的区别 3)解析ASP.NET Mvc开发之查询数据实例 4)解析ASP.NET Mvc开发之EF延迟加载 ...

  5. dotnet watch+vs code提升asp.net core开发效率

    在园子中,已经又前辈介绍过dotnet watch的用法,但是是基于asp.net core 1.0的较老版本来讲解的,在asp.net core 2.0的今天,部分用法已经不太一样,所以就再写一篇文 ...

  6. 基于C#和Asp.NET MVC开发GPS部标视频监控平台

    基于C#和Asp.NET MVC开发GPS部标监控平台 目前整理了基于.NET技术的部标平台开发文章,可以参考: 1.部标Jt808协议模拟终端的设计和开发 2.C#版的808GPS服务器开发-> ...

  7. ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  8. ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  9. 一种仿照Asp.net Mvc思维构建WebSocket服务器的方法

    问题场景 Asp.net Mvc提供了DependencyResolver.Routing.Filter. Modelbinder等webForm所没有新概念,提高Web服务编写的便利性,记得很久之前 ...

随机推荐

  1. .gitignore配置

    .gitignore文件可以配置不希望加入git的文件,例如idea的.idea 工程文件 1.配置语法 以斜杠“/”开头表示目录: 以星号“*”通配多个字符: 以问号“?”通配单个字符 以方括号“[ ...

  2. 基于tcp/udp的协议

    使用TCP协议的常见端口主要有以下几种: (1) FTP:定义了文件传输协议,使用21端口.常说某某计算机开了FTP服务便是启动了文件传输服务.下载文件,上传主页,都要用到FTP服务. (2) Tel ...

  3. CSS-页面布局

    介绍 几个实现多栏布局的方法.主要介绍使用内部div来创建浮动的栏. 多栏布局有三种基本的实现方案:固定宽度.流动.弹性. 固定宽度布局的大小是随用户调整浏览器窗口大小而变化,一般是900至1100像 ...

  4. super

    [super] Return a proxy object that delegates method calls to a parent or sibling class of type. This ...

  5. poj1741 树上的点分治

    题意: 一棵10000个点的树,每条边的长不超过1000,给定一个值k,问距离不超过k的点对数有多少.(多组数据) 输入样例: 5 4 1 2 3 1 3 1 1 4 2 3 5 1 0 0输出样例: ...

  6. win下搭建uvm环境

    UVM验证方法学,很好的验证工具,下面用ModelSim-uvm做一个Hello world. 1.安装modelsim se 10.1a 2.下载uvm_1.1d  uvm-1.1d.tar.gz  ...

  7. flask--虚拟环境

    1.安装虚拟环境mosson@mosson:~$ sudo apt-get install virtualenv2.创建一个项目目录mosson@mosson:~$ mkdir myproject3. ...

  8. LVS三种工作方式八种算法

    一.集群简介 什么是集群 计算机集群简称集群是一种计算机系统,它通过一组松散集成的计算机软件和/或硬件连接起来高度紧密地协作完成计算工作.在某种意义上,他们可以被看作是一台计算机.集群系统中的单个计算 ...

  9. python 中 深拷贝和浅拷贝的理解

    在总结 python 对象和引用的时候,想到其实 对于python的深拷贝和浅拷贝也可以很好对其的进行理解. 在python中,对象的赋值的其实就是对象的引用.也就是说,当创建一个对象,然后赋给另外一 ...

  10. boa移植

    1.交叉编译 2.复制文件 配置文件boa.conf 移动到/etc/boa/ 目录下 可执行文件boa移动到/usr/sbin/目录下 3.修改配置文件 4.将Linux系统上/etc/mime.t ...