原文信息

  • 原文地址
  • 原文作者信息
    • Justin Greenwood
    • MyGeneration Software
    • http://www.mygenerationsoftware.com/
    • October 7, 2004

系统需求:

  • Microsoft Windows 2000/XP
  • Microsoft .Net Framework 1.1/更高
  • MDAC 2.7/更高
  • MyGeneration

概观

MyGeneration目前使用了两种脚本引擎,一个是Microsoft Scripting Engine,它提供了JScript和VBScript的生成支持;另一个是 DotNetScript ,它提供了 VB.NET 和 C# 的支持。 DotNetScript 不像Microsoft Scripting Control那样的真正的脚本。实际上,它在运行时编译代码,然后利用编译后的.NET Assembly执行代码。这个教程通过例子说明使用 DotNetScript 开发MyGeneration模板的赞成与反对的理由。在这个例子中,我将使用C#和MS SQL中附带的Northwind数据库。

创建一个新的C#模板

    • 打开MyGeneration
    • 通过File->New->C# Template创建一个新的模板
    • 点击属性按钮编辑模板的属性
    • 如下图,填充模板的属性
    • 保存模板

研究默认的模板代码
默认的模板主体代码: 不像 JScript 或VBScript,C#的的模板代码相对较少。这个默认的代码是非常重要的。一个C#模板必须有一个继承了 DotNetScriptTemplate 的名为 GeneratedTemplate 的类。 MyGeneration 通过实例化 GeneratedTemplate ,并调用Render方法开始生成过程。几乎大部分的模板开发工作都在Render方法里面完成。试试执行这个模板,你将会看到literal content goes here作为输出出现。

 <%
public class GeneratedTemplate : DotNetScriptTemplate
{
public GeneratedTemplate(ZeusContext context) : base(context) {} public override void Render()
{
%>
Literal content goes here.
<%
} }
%>

默认的UI接口代码: 在默认的模板的接口代码中,同样需要一个名为GeneratedGui的,继承DotNetScriptGui的强制类。如同模板主体代码的Render方法一样, MyGeneration 将调用Setup方法开始显示用户接口并收集输入。

 public class GeneratedGui : DotNetScriptGui
{
public GeneratedGui(ZeusContext context) : base(context) {} public override void Setup()
{
}
}

获取输入:用户接口的代码块 在这个例子中,用户将通过接口选择一个表。这个是接口代码块的擅长的工作。用户接口获取的输入数据,将在模板主体代码中用来生成代码。

使用MyGeneration的接口代码:

 public class GeneratedGui : DotNetScriptGui
{
public GeneratedGui(ZeusContext context) : base(context) {} public override void Setup()
{
ui.Title = ".NetScript C# Sample: Java Class";
ui.Width = ;
ui.Height = ; // Setup Database selection combobox.
GuiLabel label_d = ui.AddLabel("lblDatabases", "Select a database:", "Select a database in the dropdown below.");
GuiComboBox cmbDatabases = ui.AddComboBox("databaseName", "Select a database."); // Setup Tables selection multi-select listbox.
GuiLabel label_t = ui.AddLabel("lblTables", "Select table:", "Select table from the combobox below.");
GuiComboBox cmbTables = ui.AddComboBox("tableName", "Select a table."); // bind data to the controls
cmbDatabases.BindData(MyMeta.Databases);
cmbDatabases.SelectedValue = MyMeta.DefaultDatabase.Name;
cmbTables.BindData( MyMeta.Databases[cmbDatabases.SelectedValue].Tables ); // Attach the onchange event to the cmbDatabases control.
cmbDatabases.AttachEvent("onchange", "cmbDatabases_onchange"); ui.ShowGui = true;
} public void cmbDatabases_onchange(GuiComboBox control)
{
GuiComboBox cmbDatabases = ui["databaseName"] as GuiComboBox;
GuiComboBox cmbTables = ui["tableName"] as GuiComboBox; cmbTables.BindData( MyMeta.Databases[cmbDatabases.SelectedValue].Tables );
}
}

使用.NET Windows Form API的接口代码:
下面的代码是不使用 MyGeneration API的替换方案,它可以达到与上面的代码同样的目的。

 <%#REFERENCE System.Windows.Forms.dll %>
<%#NAMESPACE System.Windows.Forms %>
public class GeneratedGui : DotNetScriptGui
{
public GeneratedGui(ZeusContext context) : base(context) {} public override void Setup()
{
AcquireInputForm form = new AcquireInputForm(MyMeta, input); if (form.ShowDialog() != DialogResult.OK)
{
ui.IsCanceled = true;
}
}
} public class AcquireInputForm : Form
{
private ComboBox cboDatabases = new ComboBox();
private ComboBox cboTables = new ComboBox();
private Button btnOk = new Button();
private dbRoot meta;
private IZeusInput input; public AcquireInputForm(dbRoot mymeta, IZeusInput zin)
{
this.meta = mymeta;
this.input = zin; this.BindComboBox(cboDatabases, meta.Databases);
cboDatabases.SelectedItem = meta.DefaultDatabase.Name;
cboDatabases.Top = ; cboDatabases.Left = ; cboDatabases.Width = ;
cboDatabases.SelectedIndexChanged += new EventHandler(cboDatabases_SelectedIndexChanged); this.BindComboBox(cboTables, meta.DefaultDatabase.Tables);
cboTables.Top = ; cboTables.Left = ; cboTables.Width = ; btnOk.Text = "Ok";
btnOk.Top = ; btnOk.Left = ; btnOk.Width = ;
btnOk.Click += new EventHandler(btnOk_Click); this.Controls.AddRange( new Control[] {cboDatabases, cboTables, btnOk} );
this.Text = ".NetScript C# Sample: Java Class";
this.Width = ;
this.Height = ;
} public void cboDatabases_SelectedIndexChanged(object sender, EventArgs args)
{
this.BindComboBox(
cboTables,
meta.Databases[ cboDatabases.SelectedItem.ToString() ].Tables
);
} public void btnOk_Click(object sender, EventArgs args)
{
if ((cboDatabases.SelectedIndex >= ) &&
(cboTables.SelectedIndex >= ))
{
input["databaseName"] = cboDatabases.SelectedItem.ToString();
input["tableName"] = cboTables.SelectedItem.ToString();
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
MessageBox.Show("Fill out the required fields.. PLEASE??");
}
} private void BindComboBox(ComboBox cbo, IEnumerable myMetaCollection)
{
cbo.Items.Clear();
foreach (INameValueItem item in myMetaCollection)
{
cbo.Items.Add(item.ItemValue);
}
}
}

模板主体  模板主体是生成代码的主要执行地。下面讲解了我如何生成代码的步骤。

1、将期望输出的代码放入到Render的方法中如下的代码,你将看到我将要生成的类。这几乎都是当我要生成一个模板是必做的第一件事情。

 <%
public class GeneratedTemplate : DotNetScriptTemplate
{
public GeneratedTemplate(ZeusContext context) : base(context) {} public override void Render()
{
string databaseName = input["databaseName"].ToString();
string tableName = input["tableName"].ToString();
%>
/*
* Employee.java
*
* Created on September 23, 2002, 12:59 PM
*/ package com.mygeneration.sample; import java.sql.*; import com.mygeneration.businessobjects.*;
import com.mygeneration.dataaccess.*; public class Employee extends BizObj
{
public Employee()
{
} // EmployeeID
public String getEmployeeID()
{
return getString(EmployeeSchema.EmployeeID.getFieldName());
} public void setEmployeeID(String employeeID)
{
setString(EmployeeSchema.EmployeeID.getFieldName(), employeeID);
}
}<%
} }
%>

2、添加动态代码把动态的代码添加到模板中,替换掉类名、属性名称以及数据类型。

 <%
public class GeneratedTemplate : DotNetScriptTemplate
{
public GeneratedTemplate(ZeusContext context) : base(context) {} public override void Render()
{
string databaseName = input["databaseName"].ToString();
string tableName = input["tableName"].ToString(); IDatabase database = MyMeta.Databases[databaseName];
ITable table = database.Tables[tableName];
%>/*
* <%= table.Alias %>.java
*
* Created on <%= DateTime.Now.ToString() %>
*/ package com.mygeneration.sample; import java.sql.*; import com.mygeneration.businessobjects.*;
import com.mygeneration.dataaccess.*; public class <%= table.Alias %> extends BizObj
{
public <%= table.Alias %>()
{
}
<%
foreach (IColumn column in table.Columns)
{
string datatype = this.GetJavaType(column);
%>
// <%= column.Alias %>
public <%= datatype %> get<%= column.Alias %>()
{
return get<%= datatype %>(<%= table.Alias %>Schema.<%= column.Alias %>.getFieldName());
} public void set<%= column.Alias %>(<%= datatype %> m_<%= column.Alias %>)
{
set<%= datatype %>(<%= table.Alias %>Schema.<%= column.Alias %>.getFieldName(), m_<%= column.Alias %>);
}
<%
}
%>
}<%
} private string GetJavaType(IColumn column)
{
string sqlServerType = column.DataTypeName;
int charLength = column.CharacterMaxLength; switch (sqlServerType)
{
case "bit":
return "Boolean";
case "decimal":
case "float":
case "numeric":
case "money":
case "smallmoney":
case "real":
return "Decimal";
case "tinyint":
case "smallint":
case "int":
case "bigint":
return "Integer";
case "smalldatetime":
case "datetime":
return "Timestamp";
case "varchar":
case "char":
case "nvarchar":
case "nchar":
case "text":
if (charLength == )
return "Character";
else
return "String";
default:
return "Object";
}
}
}
%>

总结

使用 DotNetScript ,你将会把 MyGeneration 的模板开发提升到一个新的水平,提供更强大的功能以及能开发更复杂的系统。

开发.Net Script 模板-MyGeneration (翻译)的更多相关文章

  1. WordPress 主题开发 - (八) Head模板 待翻译

    THE WORDPRESS THEME HEADER TEMPLATE Now we get into the nitty-gritty: building up your header.php an ...

  2. WordPress 主题开发 - (十三) Archive模板 待翻译

    What archive.php does (and all its related templates) is show posts based on a select criteria. A da ...

  3. HTML5页面开发的基础性模板

    分享一个HTML5页面开发的基础性模板,包含了两个版本: 开发版本 注释版本 开发版本 <!DOCTYPE html> <html> <head> <meta ...

  4. h5 录音 自动生成proto Js语句 UglifyJS-- 对你的js做了什么 【原码笔记】-- protobuf.js 与 Long.js 【微信开发】-- 发送模板消息 能编程与会编程 vue2入坑随记(二) -- 自定义动态组件 微信上传图片

    得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ...

  5. SpringBoot Web开发(4) Thymeleaf模板与freemaker

    SpringBoot Web开发(4) Thymeleaf模板与freemaker 一.模板引擎 常用得模板引擎有JSP.Velocity.Freemarker.Thymeleaf SpringBoo ...

  6. 分享六个基于Bootstrap的实用开发教程和模板演示

    关于Bootstrap,相信大家一定不陌生,它已经成为现在主流产业的一个重要工具,Bootstrap提供了优雅的HTML和CSS规范,它基于jQuery框架开发的,它在jQuery框架的基础上进行了更 ...

  7. freeMarker(四)——模板开发指南之模板

    学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 模板开发指南之模板 1. 总体结构 实际上用程序语言编写的程序就是模板 ...

  8. Flask开发系列之模板

    Flask开发系列之模板 本文对<FlaskWeb开发:基于python的Web应用开发实战>模板一节做的总结. Jinja2模板引擎 模板 模板是一个包含响应文本的文件,其中包含用占位变 ...

  9. 今天再给大家带点html5前端开发的干货模板“text/tpl”怎么用 script template怎么用

    text/tpl 顾名思义就是模板,其实和C++模板函数类似的作用,就是利用他生成一个HMTL内容,然后append或者替换html里面 有什么好处,假如后端返回来的数据都是一样的,但是需要生成不同的 ...

随机推荐

  1. Swift 常量、变量、条件判断

    - 常量用 let ,变量用 var - // Optional为可选项,// 可用类型值 + ? 代替 let x: Optional = 10 let y: Int? = 5 print(x! + ...

  2. HashMap从源码分析数据结构

    1. HashMap在链表中存储的是键值对 2. 数组是一块连续的固定长度的内存空间,再好的哈希函数也不能保证得到的存储地址绝对不发生冲突.那么哈希冲突如何解决呢?哈希冲突的解决方案有多种:开放定址法 ...

  3. JavaScript 中 如何判断一个元素是否在一个数组中

    <script type="text/javascript"> var arrList=['12','qw','q','v','d','t']; console.log ...

  4. (转)拉姆达表达式(Lambda Expressions) =>写法的涵义

      lambdaclass编译器 让我们先看一个简单的拉姆达表达式: x=>x/2 这个表达式的意思是:x为参数,对x进行相应的操作后的结果作为返回值. 通过这个拉姆达表达式,我们可以看到: 这 ...

  5. 使用/\_ 打印正三角形 C/C++

    输入size,level,使用/\_,打印正三角形 #include<stdio.h> int main() { int level, size; printf("Enter l ...

  6. $ each() 小结

    each()方法能使DOM循环结构简洁,不容易出错.each()函数封装了十分强大的遍历功能,使用也很方便,它可以遍历一维数组.多维数组.DOM, JSON 等等在javaScript开发过程中使用$ ...

  7. c++课设学生成绩与学籍管理系统

    题目要求(手打,累):设计一个类CStudent,类中包含一个学生的基本数据如下: 编号,姓名,性别,年龄,数学成绩,计算机成绩,外语成绩. 并假设编号为整数,且从1号往后连续编码:姓名为字符串,性别 ...

  8. 20172325『Java程序设计』课程 结对编程练习_四则运算第三周阶段总结

    20172325『Java程序设计』课程 结对编程练习_四则运算第三周阶段总结 结对伙伴 学号:20172306 姓名:刘辰 在这次项目的完成过程中刘辰同学付出了很多,在代码的实践上完成的很出色,在技 ...

  9. NC 6系预警类型注册

    在实际开发预警任务中,因为模块是新创建的,所以开发预警,就要在相应的节点模块注册.但这样代码就得放在相应的模块中,注册个预警类型,就可以把代码直接放在自己新建的模块. .先执行新建模块语句 inser ...

  10. tableView的cell之间间隔显示空白区域

    //再要创建的cell中修改frame - (void)setFrame:(CGRect)frame{ frame.origin.x += ; frame.origin.y += ; frame.si ...