文档章节

模版引擎XTemplate与代码生成器XCoder(源码)

大石头
 大石头
发布于 2010/12/21 08:34
字数 1392
阅读 380
收藏 3

    模版引擎XTemplate是一个仿T4设计的引擎,功能上基本与T4一致(模版语法上完全兼容T4,模版头指令部分兼容)。

    自己设计模版引擎,就是为了代码生成器、网站模版、邮件模版等多种场合,也就是要能拿出来单独使用、功能强大并且容易控制的。T4是个很好的引擎,但是它的设计基本上倾向于vs,几乎不顾别的场合。

    XTemplate特点如下:

    1,完全使用C#作为模版语言。跟ASP、ASP.Net页面的解析一样,把<##>标签外的文本内容当作字符串,用一个StringBuilder,标签内作为C#原生代码,拼在一起编译,进行模版替换时,实质上就是执行编译后的程序集,这就是XTemplate的核心原理!网络上现有的许许多多模版引擎,要么采用标签替换,要么自创模版语言,这些都增加了使用者的学习难度。XTemplate使用C#作为模版语言,这个世界安静了!

    2,支持“调试”。不是运行时调试,而是XTemplate能够把模版编译的中间类文件以及程序集等输出,方便检查错误。如果把模版编译后的程序集保存下来,可以在没有模版文件的情况下直接使用模版功能。

    3,不需要ASP.Net支持。有部分模版引擎,是模拟一个ASP.Net服务器,然后以ASP.Net作为模版来实现,这就要求有一个ASP.Net服务器作为宿主,限制了模版引擎的使用范围。

    4,支持批量编译。可以把多个模版放入模版处理器,进行一次编译(所有模版类都编译到一个程序集里面去)。

    5,支持类成员。模版内容默认情况下将会统一编译到一个类的Render方法里面去,但是有时候我们需要给这个类增加一些属性和方法,此时可以使用<#! #>标签,序数为单数表示开始,序数为偶数表示结束,所以不限制类成员代码的位置(T4要求只能写在模版的最后面)。

    6,支持自定义基类。默认情况下,所有编译生成的模版类都继承自TemplateBase,你也可以创建自己的模版基类,然后在模版头通过指令,或者通过外部宿主指定自定义的模版基类,模版中可以直接使用自定义模版基类的成员(因为继承嘛),比如代码生成器XCoder中的XCoderBase。

    7,自动引用宿主程序集。T4在使用上最大的麻烦就是引用外部程序集和命名空间,毕竟不是在vs里面编写C#代码。XTemplate在编译的时候,自动引用宿主(就是调用者,比如XCoder)的所有应用程序集,同时引用大部分常用的明明空间,因为这样,生成的类很臃肿,但是编译的时候,编译器会自动去掉无用的引用。XTemplate从完成到现在为止,还没有用过引用程序集和命名空间的问题,因为一般来说,模版中需要用到的程序集,宿主里面一般都有用到,非常符合我们的使用习惯。

    8,与宿主的良好交互。在XTemplate中,编译的模版程序集是直接加载在默认域,这点与T4不同,T4会新建一个域,应该是为了防止模版代码弄脏默认域的数据吧(比如干扰vs运行)。因为在同一个域,XTemplate与宿主进行交互,就不需要“翻墙”(跨域)了。XTemplate的处理过程分为分析、编译和执行三步,都可以由外部控制,比如有时候我们只是需要检查一下模版的语法,只需要检查一下模版语法是否正确,这个时候编译一下就可以了。

    9,更多的特点需要大家来发现!

 

    XCoder使用XTemplate代码(后面有XCoder的项目代码):

Dictionary<String, Object> data = new Dictionary<string, object>();
data["Config"] = Config;
data["Tables"] = Tables;
data["Table"] = table;

// 声明模版引擎
Template tt = new Template();
Template.Debug = Config.Debug;
foreach (String item in ss)
{
    if (item.EndsWith("scc", StringComparison.Ordinal)) continue;

    String tempFile = item;
    if (!Path.IsPathRooted(tempFile) && !tempFile.StartsWith(TemplatePath, StringComparison.OrdinalIgnoreCase))
        tempFile = Path.Combine(TemplatePath, tempFile);

    String content = File.ReadAllText(tempFile);

    // 添加文件头
    if (Config.UseHeadTemplate && !String.IsNullOrEmpty(Config.HeadTemplate))
        content = Config.HeadTemplate + content;

    tt.AddTemplateItem(item, content);
}
tt.Process();

// 编译模版
tt.Compile();

List<String> rs = new List<string>();
foreach (String item in ss)
{
    if (item.EndsWith("scc", StringComparison.Ordinal)) continue;

    //String content = RenderFile(table, item, data);
    String content = tt.Render(item, data);

    // 计算输出文件名
    String fileName = Path.GetFileName(item);
    String className = CutPrefix(table.Name);
    className = FixWord(className);
    String remark = table.Description;
    if (String.IsNullOrEmpty(remark)) remark = ENameToCName(className);
    if (Config.UseCNFileName && !String.IsNullOrEmpty(remark)) className = remark;
    fileName = fileName.Replace("类名", className).Replace("类说明", remark).Replace("连接名", Config.EntityConnName);

    fileName = Path.Combine(OuputPath, fileName);
    File.WriteAllText(fileName, content, Encoding.UTF8);

    rs.Add(content);
}

 

    XTemplate设计图(我喜欢先做图再编码):

XTemplate架构

作者: 大石头 发表于 2010-11-10 11:23 原文链接

评论: 32 查看评论 发表评论

最新新闻:
· 是否该让开发人员跟客户直接交流?(2010-12-21 07:53)
· 亚马逊副总裁跳槽Groupon任CFO(2010-12-21 07:50)
· Gmail语音服务将延长至2011年底(2010-12-21 07:49)
· AOL收购个人档案网站About.me(2010-12-21 07:48)
· AT&T 19.25亿美元购入高通 700MHz 低频频谱(2010-12-21 07:42)

编辑推荐:Mono又更新了

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

本文转载自:http://www.cnblogs.com/nnhy/archive/2010/11/10/1873398.html

大石头
粉丝 7
博文 67
码字总数 23240
作品 0
青浦
架构师
私信 提问
5,ORM组件XCode(动手)

本篇才真正是XCode教程第一篇。《速览》是为了以最简洁的语言最短小的篇幅去吸引开发者;《简介》则是对XCode组件和XCode开发模式的一个整体介绍,让开发者从宏观的角度去理解XCode;《共舞》...

大石头
2010/12/21
0
0
Sandbox 2.0 发布,个人网站平台

Sandbox 是一个用来搭建个人网站的平台,主要功能包括博客、相册、文件下载、网站风格定制等功能。 该版本做了大量的改进,包括使用 XTemplate 模板引擎进行重写,管理界面大改造,完全兼容 ...

红薯
2010/03/18
2.9K
3
Ext GWT 3.0 Developer Preview 1

Ext GWT是Ext和GWT整合的一个工具,可以使用GWT编写EXT为前台的程序 下载 Ext GWT 3.0 Developer Preview 1 从 3.0 开始自定义事件处理的写法简化了,如下: 或者 新的 XTemplate 模板功能:...

红薯
2011/06/17
954
1
Ext 如何通过XTemplate显示图片

Model层的图片字段是一个以逗号分隔的字符串,代表多张图片。(http://xxx.cc.1.png,http://xxx.cc.2.png,http://xxx.cc.3.png) 需要在视图层展示图片,使用rowBodyTpl : new Ext.XTemplat...

tony-cyq
2016/06/12
181
1
sencha touch2 list中自定义按钮的问题

请教大侠们,列表中的数据都是从store里面取出来的,右边的“确认”/"已确认"也是从store里面获取的,要在界面上渲染成button。已确认的话按钮还不能点击。 在list里面试了在itemTpl选项里面...

海岩奶绿
2013/02/19
990
0

没有更多内容

加载失败,请刷新页面

加载更多

Android ANR原理分析

一、概述 ANR(Application Not responding),是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR...

天王盖地虎626
9分钟前
1
0
IT兄弟连 Java语法教程 Java开发环境 安装JDK

因为我们要开发Java程序,所以必须在我们的计算机中安装Sun(Oracle)公司提供给我们的JDK。目前最新版本的JDK是JDK 10,但是我们以学习JDK 8为主,所以我们要安装的版本是JDK 8。安装步骤如...

老码农的一亩三分地
15分钟前
0
0
Spring Boot Repository查询条件关键字

查询条件关键字 Keyword Sample JPQL snippet And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2 Or findByLastnameOrFirstname … where x.lastname = ?1 or......

兜兜毛毛
21分钟前
0
0
[js]closeure闭包

// // closure 1 function func() { var count = 0; function cal(){ count += 2; console.log(count); return count; ......

Danni3
21分钟前
0
0
centos 设置hostname

1、centos 6 hostname配置文件为 /etc/sysconfig/network 内容为 NETWORKING=yesHOSTNAME=test_hostname hostname是Linux系统下的一个内核参数,它保存在 /proc/sys/kernel/hostname 下,但......

燃犀
47分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部