动软模板系列二(Model层模板)
动软模板其实和CodeSmith的模板差不多 实现的原理是一样的,但是CodeSmith貌似只支持表生成,而且不够“国人化”,所以打算研究下动软的模板,如果熟练掌握后想必以后开发项目效率可以提高很多了;
这里以典型三层的默认模板为例子:
-------------------------------------------------------------------------------------------------------------------------------------------------------
1 <#@ template language="c#" HostSpecific="True" #> 2 <#@ output extension= ".cs" #> 3 <# 4 TableHost host = (TableHost)(Host); 5 host.Fieldlist.Sort(CodeCommon.CompareByintOrder); 6 #> 7 using System; 8 using System.Text; 9 using System.Collections.Generic; 10 using System.Data; 11 namespace <#= host.NameSpace #>.Model<# if( host.Folder.Length > 0) {#>.<#= host.Folder #><# } #> 12 { 13 <# if( host.TableDescription.Length > 0) {#> 14 //<#= host.TableDescription #> 15 <# } #> 16 public class <#= host.GetModelClass(host.TableName) #> 17 { 18 19 <# foreach (ColumnInfo c in host.Fieldlist) 20 { #>/// <summary> 21 /// <#= string.IsNullOrEmpty(c.Description) ? c.ColumnName : c.Description #> 22 /// </summary> 23 private <#= CodeCommon.DbTypeToCS(c.TypeName) #> _<#= c.ColumnName.ToString().ToLower() #>; 24 public <#= CodeCommon.DbTypeToCS(c.TypeName) #> <#= c.ColumnName #> 25 { 26 get{ return _<#= c.ColumnName.ToString().ToLower()#>; } 27 set{ _<#= c.ColumnName.ToString().ToLower() #> = value; } 28 } 29 <# } #> 30 31 } 32 }
模板的大体分为5块内容:模板指令声明,代码语句块,表达式块,类功能控制块,文本块输出。下面我们分别来介绍一下这5块内容的语法和使用说明。
- ----------------模板指令声明块 <#@ #>------------------------------
按行拆分:
1 <#@ template language="c#" HostSpecific="True" #>
2 <#@ output extension= ".cs" #>
讲解:
<#@ template language="c#" HostSpecific="True" #>
模板指令声明,template language="c#" 代表生成的是基于C#语言的模板,
hostSpecific="true" 表示是否使用特定的host,host里面包含了模板使用的各种对象。 (这句一般默认即可)
<#@ output extension= ".cs" #>
这句代表是输入.CS的文件
注意:
所有属性值(="c#",="True",= ".cs" ...)必须用双引号都括起来。如果值本身包含引号,则必须使用 \ 字符对这些引号进行转义。 指令通常是模板文件或包含的文件中的第一个元素(所有模板必须要有这两句)。
---------关于此块官方更详细的讲解(一般只用到上面这两句就可以了)---------------
和ASP.NET页面的指令一样,它们出现在文件头,通过<#@…#>表示。其中<#@ template …#>指令是必须的,用于定义模板的基本属性。
(1) 模板指令
<#@ template [language="VB"] [hostspecific="true"] [debug="true"] [inherits="templateBaseClass"] [culture="code"] [compilerOptions="options"] #>
例如
<#@ template language="C#v3.5" hostSpecific="true" debug="true" #>
Language 这里可以指定模板使用的语言。
hostSpecific="true" 表示是否使用特定的host,host里面包含了模板使用的各种对象。
注意:
所有属性值必须用双引号都括起来。如果值本身包含引号,则必须使用 \ 字符对这些引号进行转义。 指令通常是模板文件或包含的文件中的第一个元素。
(2) 参数指令
<#@ parameter type="Full.TypeName" name="ParameterName" #>
(3) 输出指令
<#@ output extension=".fileNameExtension" encoding="encoding" #>
- output extension=".cs" 指定生成文件的扩展名。
encoding="encoding" 指定生成文件的编码。
(4) 程序集指令
<#@ assembly name="System.Data" #>
用于添加程序集引用,如果要使用第三方程序集,那么最好在项目中添加引用。
注:您应使用绝对路径的名称,或者路径名称中使用标准的宏的名称。
例如: <#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>
(5) 导入指令
<#@ import namespace="System.Data" #>
导入要使用的命名空间,注意:这里的命名空间必须要在前面指定的程序集里面找得到的,比如我指定命名空间"System.Data","System.Data.Common",这些在程序集System.Data中都有的
(6) 包含指令
<#@ include file="test.tt" #> 导入模板,类似Html的include用法
include 指令插入其他模板文件的文本。
例如,下面的指令插入 test.txt 的内容。 <#@ include file="c:\test.txt" #>
在处理时,被包含内容就像是包含文本模板的组成部分一样。 不过,即使 include 指令后跟普通文本块和标准控制块,也可以包含编写有类功能块 <#+...#> 的文件
--------------------2.代码语句块: <# #>--------------------------------
在模板文件中,可以混合使用任意数量的文本块和标准控制块。中间是一段通过相应编程语言编写的程序调用,我们可以通过代码语句块控制文本转化的流程。
注意:不能在控制块中嵌套控制块。
<#@ output extension=".txt" #>
<#
for(int i = 0; i < 4; i++)
{
#>
Hello!
<#
}
#>
------------------看默认的Model模板:-------------
3 <#
4 TableHost host = (TableHost)(Host);
5 host.Fieldlist.Sort(CodeCommon.CompareByintOrder);
6 #>
---------------------
TableHost host = (TableHost)(Host);
这句应该是创建host对象,以便调用host对象下的一系列方法和属性等,类似于C#的New;
host.Fieldlist.Sort(CodeCommon.CompareByintOrder);
Fieldlist = 字段集合,类型为List<ColumnInfo>,ColumnInfo=字段信息对象;
CodeCommon 是个工具类, CompareByintOrder 这个官方没有给出说明;
这句的意思是取得字段列表并按照一定顺序排序;
--------------------------------------------
7 using System;
8 using System.Text;
9 using System.Collections.Generic;
10 using System.Data;
这些都是固定的命名空间,文本按原样输出!!!
------------官方注解和示例:---
5.文本块输出
可以使用 Write() 和 WriteLine() 方法在标准代码块内追加文本,而不必使用表达式代码块。 它们可帮助缩进输出和报告错误。
下面两个代码块在功能上是等效的。
包含表达式块的代码块
<#
int i = 10;
while (i-- > 0)
{ #>
<#= i #>
<# }
#>
使用 WriteLine() 的代码块
<#
int i = 10;
while (i-- > 0)
{
WriteLine((i.ToString()));
}
#>
Write() 和 WriteLine() 方法有两个重载,其中一个重载接受单个字符串参数,另一个重载接受一个复合格式字符串以及将包含在字符串中的对象数组(与 Console.WriteLine() 方法类似)。
下面两种 WriteLine() 用法在功能上是等效的:
<#
string msg = "Say: {0}, {1}, {2}";
string s1 = "hello";
string s2 = "goodbye";
string s3 = "farewell";
WriteLine(msg, s1, s2, s3);
WriteLine("Say: hello, goodbye, farewell");
#>
设置文本模板输出缩进的格式。
CurrentIndent 字符串属性显示文本模板中的当前缩进,该类还具有一个 indentLengths 字段,该字段是已添加的缩进的列表。
PushIndent() 方法增加缩进,
PopIndent() 方法减少缩进。
ClearIndent() 方法,删除所有缩进。
下面的代码块演示这些方法的用法:
<#
WriteLine(CurrentIndent + "Hello");
PushIndent(" ");
WriteLine(CurrentIndent + "Hello");
PushIndent(" ");
WriteLine(CurrentIndent + "Hello");
ClearIndent();
WriteLine(CurrentIndent + "Hello");
PushIndent(" ");
WriteLine(CurrentIndent + "Hello");
#>
此代码块产生以下输出:
Hello
Hello
Hello
Hello
Hello
------------------------------------
11 namespace <#= host.NameSpace #>.Model<# if( host.Folder.Length > 0) {#>.<#= host.Folder #><# } #>
命名空间:这句比较简单,host.NameSpace 获取host对象的命名空间,以及是否加后缀(一般是没有后缀了...,Folder 官方解释是所属文件夹的意思,类型是字符串,这里不太明白希望有人讲解下);
12 {
13 <# if( host.TableDescription.Length > 0) {#>
14 //<#= host.TableDescription #>
15 <# } #>
如果此表有描述信息,将在此显示:如
/// <summary>
/// 广告管理 (表描述)
/// </summary>
16 public class <#= host.GetModelClass(host.TableName) #>
17 {
根据表名获取Model类名
官方注解:
3.表达式块:<#= #>
表达式控制块计算表达式并将其转换为字符串。 该字符串将插入到输出文件中。
例如: <#= 2 + 3 #>
表达式可以包含作用域中的任何变量。 例如,下面的块输出数字行:
<#@ output extension=".txt" #>
<#
for(int i = 0; i < 4; i++)
{
#>
This is hello number <#= i+1 #>: Hello!
<#
}
#>
-------------------------------
18
19 <# foreach (ColumnInfo c in host.Fieldlist)
20 { #>/// <summary>
21 /// <#= string.IsNullOrEmpty(c.Description) ? c.ColumnName : c.Description #>
22 /// </summary>
23 private <#= CodeCommon.DbTypeToCS(c.TypeName) #> _<#= c.ColumnName.ToString().ToLower() #>;
24 public <#= CodeCommon.DbTypeToCS(c.TypeName) #> <#= c.ColumnName #>
25 {
26 get{ return _<#= c.ColumnName.ToString().ToLower()#>; }
27 set{ _<#= c.ColumnName.ToString().ToLower() #> = value; }
28 }
29 <# } #>
30
31 }
32 }
<# foreach (ColumnInfo c in host.Fieldlist)
遍历字段集合
<#= string.IsNullOrEmpty(c.Description) ? c.ColumnName : c.Description #>
字段说明不为空的话在此显示
private <#= CodeCommon.DbTypeToCS(c.TypeName) #> _<#= c.ColumnName.ToString().ToLower() #>;
DbTypeToCS = 得到“数据库字段类型”对应的“c#类型”
这句是得到数据库字段类型对应的C#类型 并添加“_”: 如 private int _id;
24 public <#= CodeCommon.DbTypeToCS(c.TypeName) #> <#= c.ColumnName #>
25 {
26 get{ return _<#= c.ColumnName.ToString().ToLower()#>; }
27 set{ _<#= c.ColumnName.ToString().ToLower() #> = value; }
28 }
29 <# } #>
设置属性,同样是获取对应的C#类型 并设置 get set的值(与下划线的字段相对应);
-----------------------------------下篇介绍DAL层模板-------------------