Razor Engine,实现代码生成器的又一件利器
Razor Engine,之前仅仅是ASP.NET MVC的一种View引擎,目前已经完全成为一种可以独立使用的模版引擎,并且已经成为了CodePlex上一个开源的项目(http://razorengine.codeplex.com/)。对于使用过ASP.NET MVC Razor视图引擎的朋友们一定已经领略过它的灵活性和易用性,在这篇文章中我们将利用它来实现一个代码生成器使我们可以以Razor的语法来定义代码模版。[源代码从这里下载]
在《一个简易版的T4代码生成"框架"》这篇文章中,我创建了一个能够生成多个文件的代码生成器,其核心是两个基本的类型:Template类生成代码文件的内容,Generator执行Template。现在我将通过自定义一个基于Razor Engine的Template,让它读取以Razor语法编写的模版文件并生成相应的代码。
不过在具体介绍实现原理之前,还是先来看看它能够达到的效果。如右图所示,我们还是通过一个.tt文件(Generator.tt)来生成相应的代码文件,具体生成的代码文件就是依赖于该.tt文件的三个.cs 文件:Foo.cs、Bar.cs和Baz.cs。简单起见,我们仅仅在这三个文件中生成了一个与文件同名的空Class,它们的定义如下。
1: public class Foo
2: {
3: }
4:
5: public class Bar
6: {
7: }
8:
9: public class Baz
10: {
11: }
如下所示的是Generator.tt的内容,它直接执行一个类型为DemoGenerator的生成器。
1: <#@ template hostspecific="true" language="C#" #>
2: <#@ assembly name="$(TargetDir)Artech.CodeGeneration.dll" #>
3: <#@ import namespace="Artech.CodeGeneration" #>
4: <#@ output extension=".empty" #>
5: <#this.RunCodeGenerator(this.Host, new DemoGenerator());#>
作为代码生成器的DemoGenerator定义如下,它重写了CreateTemplates方法并返回一个包含三个RazorTemplate<TModel>的字典,该字典的Key表示生成的文件名。
1: public class DemoGenerator: Generator
2: {
3: protected override IDictionary<string, Template> CreateTemplates()
4: {
5: Dictionary<string, Template> templates = new Dictionary<string, Template>();
6: templates.Add("Foo.cs", new RazorTemplate<string>("template.razor", "Foo"));
7: templates.Add("Bar.cs", new RazorTemplate<string>("template.razor", "Bar"));
8: templates.Add("Baz.cs", new RazorTemplate<string>("template.razor", "Baz"));
9: return templates;
10: }
11: }
构建RazorTemplate<TModel>需要传入两个参数,第一个参数是用于定义Razor模版的文件路径(可以是绝对路径,也可以是相对于.tt文件的相对路径),另一个是作为Model的对象(相当于ASP.NET强类型View的Model)。通过上面的代码可以看出,三个RazorTemplate<TModel>均使用同一个Model类型为字符串的模版文件template.razor,该模版内容定义如下。可以看出作为Model的字符串在模版中作为了生成类型的名称。
1: public class @Model
2: {
3: }
我假设你已经了解了《一个简易版的T4代码生成"框架"》这篇文章的内容,所以我们只需要简单介绍RazorTemplate<TModel>的定义就可以了。首选RazorTemplate<TModel>是一个具有如下定义的RazorTemplate类型的子类。RazorTemplate的只读属性TemplateFileName 表示Razor模版的路径,用于读取模版文本内容的虚方法GetTemplateText直接读取指定模版文件的内容。在重写的TransformText方法中,我们调用Razor的静态方法Parse对模版内容进行解析并生成代码文本。
1: public class RazorTemplate : Template
2: {
3: public string TemplateFileName { get; private set; }
4: public RazorTemplate(string templateFileName)
5: {
6: this.TemplateFileName = templateFileName;
7: }
8: protected virtual string GetTemplateText()
9: {
10: string path = this.TemplateFileName;
11: if (!Path.IsPathRooted(path))
12: {
13: path = Path.Combine(Path.GetDirectoryName(TransformContext.Current.Host.TemplateFile), path);
14: }
15: return File.ReadAllText(path);
16: }
17:
18: public override string TransformText()
19: {
20: return Razor.Parse(this.GetTemplateText());
21: }
22: }
继承自RazorTemplate的泛型RazorTemplate<TModel>定义如下。它具有一个表示Model的只读属性,该属性在构造函数中被初始化。在重写的TransformText方法中,我们调用Razor泛型的静态方法Parse<TModel>解析模版文本并传入Model对象。
1: public class RazorTemplate<TModel> : RazorTemplate
2: {
3: public TModel Model { get; private set; }
4: public RazorTemplate(string templateFileName, TModel model)
5: : base(templateFileName)
6: {
7: this.Model = model;
8: }
9:
10: public override string TransformText()
11: {
12: return Razor.Parse<TModel>(this.GetTemplateText(), this.Model);
13: }
14: }
相关阅读:
与VS集成的若干种代码生成解决方案[博文汇总(共8篇)]通过Visual Studio的Custom Tool定义代码生成器
Razor Engine,实现代码生成器的又一件利器的更多相关文章
- [2018-08-25]模板引擎Razor Engine 用法示例
好久没写博客了,回宁波后最近几个月一直忙些线下的事情. 敲代码方面脱产有阵子了,生疏了,回头一看,这行业果然更新飞快. 最近线下的事情基本忙完,准备开始干回老本行,最重要的一件事就是升级abplus库 ...
- Terminologies in MVC: Part 2 (Razor Engine Syntax vs Web Form)
By Abhishek Jaiswal :) on Mar 21, 2015 In this article we learn about Razor Engine Syntax vs Web For ...
- VS2010下WPF开发ARCGIS ENGINE 10的带Ribbon控件项目
原文 http://blog.sina.com.cn/s/blog_47522f7f0100nq5t.html 题目好长,但是集目前最新的工具于一身..VS是最新的2010版,不过用的是.net3.5 ...
- Razor Engine,动态脚本语言,mvc上的语法,适用于文件内容生成,静态网页生成等。
https://razorengine.codeplex.com/ 下载并引用:razorengine.dll 代码里这样写,用mvc的人都会!Razor语法! string template = & ...
- Razor - 模板引擎 / 代码生成 - RazorEngine
目录 Brief Authors Official Website RazorEngine 的原理 - 官方解释 安装记录 Supported Syntax (默认实现支持的语法) 测试记录 - ca ...
- asp.net mvc简单实现基于Razor的分页控件
最近在写一些web应用了解了一下asp.net mvc发现的确好用,所以直接就干上了.不过在使用asp.net mvc的Razor模板的情况并不向传统webform那样可以使用控件.但从Razor的功 ...
- A Look at the Razor View Engine in ASP.NET MVC
The biggest architectural difference that exists between ASP.NET MVC and ASP.NET Web Forms is the ne ...
- mvc 4 Razor (@html.xx)语法大全以及应用
Razor语法大全 @Html ASP.NET MVC 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction差别 对这 ...
- FreeSql.Generator命令行代码生成器是如何实现的
目录 FreeSql介绍 FreeSql.Generator RazorEngine.NetCore 源码解析 FreeSql.Tools FreeSql FreeSql 是功能强大的对象关系映射技术 ...
随机推荐
- StringBuilder(字符串拼接类)
StringBuilder是在using System.Text命名空间下的一个成员. 在做字符串拼接的时候,因为字符串是引用类型,新的字符串是会再内存中创建的,所以用+号拼接字符串是比较耗效率的. ...
- WeX5学习笔记
目录 WeX5学习笔记... 1 1.轻松看透WeX5产品能力和技术... 1 2.WeX5可以怎么玩?... 3 一.纯本地App. 3 二.关联一个网站,希望默认就打开某页... 4 三.UI设计 ...
- problem-eclipse创建maven项目报错
Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5 or one of ...
- h5 audio标签在手机上不能自动播放????
最近在做一个微信端的项目,快到接近尾声的时候,发现还没放入音频,于是乎,放入音频,在电脑端测试一切正常,无阻碍. 后来在手机上测试,发现背景音乐不能播放,于是开始找错,刚开始以为是IIS服务器出错,结 ...
- GitHub for Windows 內建 Git Shell 執行時顏色所代表的意義
在使用指令列版控的過程中,經常有機會用到 Git Shell 這套優異的 Git 版控環境,一來他使用 Windows PowerShell 為核心,其訊息顯示與輸入都支援 Unicode,比較不會有 ...
- hoj 1014 Niven Numbers
新手上路之我的水题之路 刚开始时,我首先想到的是定义一个int数组,然后让输入的数字从最低位开始在循环不断地*base,从而将 k进制转化成十进制:然后再作取模判断就可以了: 这时在将最低位到最高位依 ...
- int与string类型的转换
在SQL语句中 在JS中, (1) var x=100 a = x.toString() (2) var x=100; a = x +"" ...
- Java NIO4:Socket通道
Socket通道 上文讲述了通道.文件通道,这篇文章来讲述一下Socket通道,Socket通道与文件通道有着不一样的特征,分三点说: 1.NIO的Socket通道类可以运行于非阻塞模式并且是可选择的 ...
- Java NIO3:通道和文件通道
通道是什么 通道式(Channel)是java.nio的第二个主要创新.通道既不是一个扩展也不是一项增强,而是全新的.极好的Java I/O示例,提供与I/O服务的直接连接.Channel用于在字节缓 ...
- Java NIO2:缓冲区
什么是缓冲区 一个缓冲区对象是固定数量的数据的容器,其作用是一个存储器,或者分段运输区,在这里数据可被存储并在之后用于检索.缓冲区像前篇文章讨论的那样被写满和释放,对于每个非布尔原始数据类型都有一个缓 ...