从零开始编写自己的C#框架(12)——T4模板在逻辑层中的应用(一)(附源码)
对于T4模板很多朋友都不太熟悉,它在项目开发中,会帮我们减轻很大的工作量,提升我们的开发效率,减少出错概率。所以学好T4模板的应用,对于开发人员来说是非常重要的。
园子里对于T4模板的介绍与资料已经太多了,所以在这里我就不再详细讲述基础知识了,只是说说T4模板在本框架中的具体应用与实践。
一、创建逻辑层项目
二、添加引用
将之前添加的三个项目添加到引用
三、创建T4模板放置的文件夹,并命名为SubSonic
四、将Solution.DataAccess项目中SubSonic文件夹下的MultipleOutputHelper.ttinclude、Settings.ttinclude、SQLServer.ttinclude以及项目根目录下的App.config四个文件复制到逻辑层对应的位置里,详见下图
五、SubSonic文件夹里创建Test.tt模板文件,用来练习T4模板的实践
六、编写T4模板实例,练习模板的使用
1、练习一
我们先添加几行代码
1 <#@ template language="C#" debug="false" hostspecific="True" #> 2 <#@ output extension=".cs" encoding="utf-8" #> 3 <#@ include file="SQLServer.ttinclude" #> 4 5 using System; 6 7 namespace <#=Namespace#> { 8 9 }
<#@ template language="C#" debug="false" hostspecific="True" #>是T4模板指令,说明使用的语言是C#,不开启debug模式,并将名为 Host 的属性添加到由文本模板生成的类中
<#@ output extension=".cs" encoding="utf-8" #>是T4模板的输出指令,限制当前模板生成的文件扩展名为.cs,存储格式为utf-8
<#@ include file="SQLServer.ttinclude" #>这是模板的工具类文件,使用 Include 指令在其他文本模板中包含此文件,本行代码主要功能是将SQL操作的工具类(函数)包含到代码
using System; 这是输出在cs文件中显示的文本信息,具体功能大家一看就明白了,不再解释
namespace <#=Namespace#> 创建命名空间名称,因为SQLServer.ttinclude文件里使用了<#@ include file="Settings.ttinclude" #>,将SubSonic3.0模板的配置信息也同时读取了进来,所以可以直接使用Settings.ttinclude中设置的变量,用它来作为命名空间名称,详见下图
也就是说,如果你想在模板中使用一些你想要的变量的话,可以在这些工具类或配置文件中进行定义
点击保存后生成Test.cs文件内容:
2、练习二
通过练习一,我们明白了T4模板生成代码的简单原理,那么我们增加些实用的内容来看看模板运行的效果
先上代码
1 <#@ template debug="false" hostspecific="True" language="C#" #> 2 <#@ output extension=".cs" encoding="utf-8" #> 3 <#@ include file="SQLServer.ttinclude" #> 4 5 using System; 6 7 namespace <#=Namespace#> { 8 <# 9 var tables = LoadTables(); 10 //遍历所有表 11 foreach(var tbl in tables){ 12 #> 13 17 public class <#=tbl.CleanName#>Table { 18 /// <summary> 19 /// 表名 20 /// </summary> 21 public static string TableName { 22 get{ 23 return "<#=tbl.CleanName#>"; 24 } 25 } 26 } 27 <# 28 } 29 #> 30 }
var tables = LoadTables(); LoadTables()是SQLServer.ttinclude工具类中的函数,功能是获取数据库中所有表和字段(已修改了该文件的代码,可以获取到所有表与视图)
foreach(var tbl in tables) 遍历所有表
<#=tbl.CleanName#> 读取表名称
public class <#=tbl.CleanName#>Table 用表名称+Table 做为类名
点击保存后生成Test.cs文件内容:
3、练习三
通过上面练习,我们可以看到使用很简单的几行代码,就可以非常方便的生成我们想要的代码,减少我们复制粘贴的操作,当然上面生成的东西太简单了,我们想通过本模板生成的类来减少强编码,那么就需要获取所有字段名称出来
1 <#@ template debug="false" hostspecific="True" language="C#" #> 2 <#@ output extension=".cs" encoding="utf-8" #> 3 <#@ include file="SQLServer.ttinclude" #> 4 5 using System; 6 7 namespace <#=Namespace#> { 8 <# 9 var tables = LoadTables(); 10 //遍历所有表 11 foreach(var tbl in tables){ 12 #> 13 14 public class <#=tbl.CleanName#>Table { 15 /// <summary> 16 /// 表名 17 /// </summary> 18 public static string TableName { 19 get{ 20 return "<#=tbl.CleanName#>"; 21 } 22 } 23 24 25 26 //新增代码,循环遍历表中的所有字段,创建相应的函数 27 <# 28 foreach(var col in tbl.Columns){ 29 #> 30 /// <summary> 31 /// <#=Replace(col.Description) #> 32 /// </summary> 33 public static string <#= col.Name #>{ 34 get{ 35 return "<#= col.Name #>"; 36 } 37 } 38 39 <# 40 } 41 #> 42 43 44 45 46 } 47 <# 48 } 49 #> 50 }
foreach(var col in tbl.Columns) 遍历表中所有字段,获取字段结构
<#=Replace(col.Description) #> 本代码中通过col.Description来获取字估注释,Replace函数是将字段注释(说明)里的换行符替换成对应格式
<#= col.Name #> 获取字段名称
点击保存后生成Test.cs文件内容:
4、练习四
用完上面的练习是不是感觉很简单呢。对于数据表比较少的情况下,这种生成是完全没有问题的,但表多了以后都放在一个文件里,在DEBUG调试时就会出问题了,主要原因是代码行数过大,所以我们有另外一种解决办法,就是分文件生成
先上代码(为了让大家更好的理解,会将前面例子中的一些内容删除掉)
1 <#@ template debug="false" hostspecific="True" language="C#" #> 2 <#@ output extension=".cs" encoding="utf-8" #> 3 <#@ include file="SQLServer.ttinclude" #> 4 <#@ include file="MultipleOutputHelper.ttinclude"#> 5 6 <# 7 //获取所有表与视图 8 var tables = LoadTables(); 9 //创建多文件生成实体 10 var manager = Manager.Create(Host, GenerationEnvironment); 11 12 //遍历所有表 13 foreach(var tbl in tables){ 14 //判断当前表名是否是禁用名称(禁用的名称可以在Settings.ttinclude文件的ExcludeTables字符串数据中进行添加) 15 if(!ExcludeTables.Contains(tbl.Name)) 16 { 17 // 设置输出的文件名 18 manager.StartNewFile(tbl.ClassName+".cs"); 19 #> 20 using System; 21 22 namespace <#=Namespace#> { 23 24 } 25 26 27 <# 28 // 输出文件结束 29 manager.EndBlock(); 30 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束 31 32 }// end foreach 33 34 // 执行编译,生成文件 35 manager.Process(true); 36 #>
<#@ include file="MultipleOutputHelper.ttinclude"#> 生成多文件工具类
var manager = Manager.Create(Host, GenerationEnvironment); 创建多文件生成实体
foreach(var tbl in tables) 遍历所有表,这个放在using的前面,是因为每个单独文件生成后都需要有using
其他新增内容在代码中都有详细注释了,所以这里不再说明
点击保存后生成Test.cs文件内容:
再来个完整的模板代码
1 <#@ template debug="false" hostspecific="True" language="C#" #> 2 <#@ output extension=".cs" encoding="utf-8" #> 3 <#@ include file="SQLServer.ttinclude" #> 4 <#@ include file="MultipleOutputHelper.ttinclude"#> 5 6 <# 7 //获取所有表与视图 8 var tables = LoadTables(); 9 //创建多文件生成实体 10 var manager = Manager.Create(Host, GenerationEnvironment); 11 12 //遍历所有表 13 foreach(var tbl in tables){ 14 //判断当前表名是否是禁用名称(禁用的名称可以在Settings.ttinclude文件的ExcludeTables字符串数据中进行添加) 15 if(!ExcludeTables.Contains(tbl.Name)) 16 { 17 // 设置输出的文件名 18 manager.StartNewFile(tbl.ClassName+".cs"); 19 #> 20 using System; 21 22 namespace <#=Namespace#> { 23 24 public class <#=tbl.CleanName#>Table { 25 /// <summary> 26 /// 表名 27 /// </summary> 28 public static string TableName { 29 get{ 30 return "<#=tbl.CleanName#>"; 31 } 32 } 33 34 <# 35 foreach(var col in tbl.Columns){ 36 #> 37 /// <summary> 38 /// <#=Replace(col.Description) #> 39 /// </summary> 40 public static string <#= col.Name #>{ 41 get{ 42 return "<#= col.Name #>"; 43 } 44 } 45 46 <# 47 } 48 #> 49 } 50 51 } 52 53 54 <# 55 // 输出文件结束 56 manager.EndBlock(); 57 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束 58 59 }// end foreach 60 61 // 执行编译,生成文件 62 manager.Process(true); 63 #>
点击保存后生成Test.cs文件内容:
下载地址:
版权声明:
本文由AllEmpty原创并发布于博客园,欢迎转载,未经本人同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如有问题,可以通过1654937@qq.com 联系我,非常感谢。
发表本编内容,只要主为了和大家共同学习共同进步,有兴趣的朋友可以加加Q群:327360708 ,大家一起探讨。
更多内容,敬请观注博客:http://www.cnblogs.com/EmptyFS/