yycGIS

我们曾如此渴望命运的波澜,到最后才发现:人生最曼妙的风景,竟是内心的淡定与从容。 我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系。

Less is more, more is different!

导航

开发.Net Script 模板-MyGeneration (翻译)

原文信息

  • 原文地址
  • 原文作者信息
    • 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作为输出出现。

 1 <%
 2  public class GeneratedTemplate : DotNetScriptTemplate
 3  {
 4         public GeneratedTemplate(ZeusContext context) : base(context) {}
 5 
 6 
 7         public override void Render()
 8         {
 9  %>
10  Literal content goes here.
11  <%
12         }
13 
14 
15  }
16  %>

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

1 public class GeneratedGui : DotNetScriptGui
2  {
3         public GeneratedGui(ZeusContext context) : base(context)           {}
4 
5 
6         public override void Setup()
7         {
8         }
9  }

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


使用MyGeneration的接口代码:

 1 public class GeneratedGui : DotNetScriptGui
 2  {
 3         public GeneratedGui(ZeusContext context) : base(context) {}
 4 
 5 
 6         public override void Setup()
 7         {
 8                 ui.Title = ".NetScript C# Sample: Java Class";
 9                 ui.Width = 340;
10                 ui.Height = 200;
11 
12 
13                 // Setup Database selection combobox.
14                 GuiLabel label_d = ui.AddLabel("lblDatabases", "Select a database:", "Select a database in the dropdown below.");
15                 GuiComboBox cmbDatabases = ui.AddComboBox("databaseName", "Select a database.");
16 
17 
18                 // Setup Tables selection multi-select listbox.
19                 GuiLabel label_t = ui.AddLabel("lblTables", "Select table:", "Select table from the combobox below.");
20                 GuiComboBox cmbTables = ui.AddComboBox("tableName", "Select a table.");
21 
22 
23                 // bind data to the controls
24                 cmbDatabases.BindData(MyMeta.Databases);
25                 cmbDatabases.SelectedValue = MyMeta.DefaultDatabase.Name;
26                 cmbTables.BindData( MyMeta.Databases[cmbDatabases.SelectedValue].Tables );
27 
28                 // Attach the onchange event to the cmbDatabases control.
29                 cmbDatabases.AttachEvent("onchange", "cmbDatabases_onchange");
30 
31                 ui.ShowGui = true;
32         }
33 
34 
35         public void cmbDatabases_onchange(GuiComboBox control)
36         {
37                 GuiComboBox cmbDatabases = ui["databaseName"] as GuiComboBox;
38                 GuiComboBox cmbTables = ui["tableName"] as GuiComboBox;
39 
40 
41                 cmbTables.BindData( MyMeta.Databases[cmbDatabases.SelectedValue].Tables );
42         }
43  }

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

 1 <%#REFERENCE System.Windows.Forms.dll %>
 2  <%#NAMESPACE System.Windows.Forms %>
 3  public class GeneratedGui : DotNetScriptGui
 4  {
 5         public GeneratedGui(ZeusContext context) : base(context) {}
 6 
 7 
 8         public override void Setup() 
 9         {
10                 AcquireInputForm form = new AcquireInputForm(MyMeta, input); 
11 
12 
13                 if (form.ShowDialog() != DialogResult.OK) 
14                 {
15                         ui.IsCanceled = true;
16                 }
17         }
18  }
19 
20 
21  public class AcquireInputForm : Form
22  {
23         private ComboBox cboDatabases = new ComboBox();
24         private ComboBox cboTables = new ComboBox();
25         private Button btnOk = new Button();
26         private dbRoot meta;
27         private IZeusInput input;
28 
29 
30         public AcquireInputForm(dbRoot mymeta, IZeusInput zin)
31         {
32                 this.meta = mymeta;
33                 this.input = zin;
34 
35 
36                 this.BindComboBox(cboDatabases, meta.Databases);
37                 cboDatabases.SelectedItem = meta.DefaultDatabase.Name;
38                 cboDatabases.Top = 10; cboDatabases.Left = 10; cboDatabases.Width =  200;
39                 cboDatabases.SelectedIndexChanged += new EventHandler(cboDatabases_SelectedIndexChanged);
40 
41 
42                 this.BindComboBox(cboTables, meta.DefaultDatabase.Tables);
43                 cboTables.Top = 50; cboTables.Left = 10; cboTables.Width =  200;
44 
45 
46                 btnOk.Text = "Ok";
47                 btnOk.Top = 100; btnOk.Left = 10; btnOk.Width = 200;
48                 btnOk.Click += new EventHandler(btnOk_Click);
49 
50 
51                 this.Controls.AddRange( new Control[] {cboDatabases, cboTables, btnOk} );
52                 this.Text = ".NetScript C# Sample: Java Class";
53                 this.Width = 230;
54                 this.Height = 160;
55         }
56 
57 
58         public void cboDatabases_SelectedIndexChanged(object sender, EventArgs args) 
59         {
60                 this.BindComboBox(
61                                 cboTables, 
62                                 meta.Databases[ cboDatabases.SelectedItem.ToString() ].Tables 
63                         );
64         }
65 
66 
67         public void btnOk_Click(object sender, EventArgs args) 
68         {
69                 if ((cboDatabases.SelectedIndex >= 0) &&
70                         (cboTables.SelectedIndex >= 0)) 
71                 {
72                         input["databaseName"] = cboDatabases.SelectedItem.ToString();
73                         input["tableName"] = cboTables.SelectedItem.ToString();
74                         this.DialogResult = DialogResult.OK;
75                         this.Close();
76                 }
77                 else 
78                 {
79                         MessageBox.Show("Fill out the required fields.. PLEASE??");
80                 }
81         }
82 
83 
84         private void BindComboBox(ComboBox cbo, IEnumerable myMetaCollection)
85         {
86                 cbo.Items.Clear();
87                 foreach (INameValueItem item in myMetaCollection)
88                 {
89                         cbo.Items.Add(item.ItemValue);
90                 }
91         }
92  }

 

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

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

 1 <%
 2  public class GeneratedTemplate : DotNetScriptTemplate
 3  {
 4         public GeneratedTemplate(ZeusContext context) : base(context) {}
 5 
 6 
 7         public override void Render()
 8         {
 9                 string databaseName = input["databaseName"].ToString();
10                 string tableName = input["tableName"].ToString();
11  %>
12 /*
13  * Employee.java
14  *
15  * Created on September 23, 2002, 12:59 PM
16  */
17 
18 
19  package com.mygeneration.sample;
20 
21 
22  import java.sql.*;
23 
24 
25  import com.mygeneration.businessobjects.*;
26  import com.mygeneration.dataaccess.*;
27 
28 
29  public class Employee extends BizObj
30  {
31     public Employee() 
32     {
33     }
34 
35 
36     // EmployeeID
37     public String getEmployeeID()
38     {
39         return getString(EmployeeSchema.EmployeeID.getFieldName());
40     }
41 
42 
43     public void setEmployeeID(String employeeID)
44     {
45         setString(EmployeeSchema.EmployeeID.getFieldName(), employeeID);
46     }    
47  }<%
48         }
49 
50 
51  }
52  %>

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

 1 <%
 2  public class GeneratedTemplate : DotNetScriptTemplate
 3  {
 4         public GeneratedTemplate(ZeusContext context) : base(context) {}
 5 
 6 
 7         public override void Render()
 8         {
 9                 string databaseName = input["databaseName"].ToString();
10                 string tableName = input["tableName"].ToString();
11 
12 
13                 IDatabase database = MyMeta.Databases[databaseName];
14                 ITable table = database.Tables[tableName];
15  %>/*
16  * <%= table.Alias %>.java
17  *
18  * Created on <%= DateTime.Now.ToString() %>
19  */
20 
21 
22  package com.mygeneration.sample;
23 
24 
25  import java.sql.*;
26 
27 
28  import com.mygeneration.businessobjects.*;
29  import com.mygeneration.dataaccess.*;
30 
31 
32  public class <%= table.Alias %> extends BizObj
33  {
34     public <%= table.Alias %>() 
35     {
36     }
37  <%
38                 foreach (IColumn column in table.Columns)
39                 {
40                         string datatype = this.GetJavaType(column);
41  %>    
42     // <%= column.Alias %>
43     public <%= datatype %> get<%= column.Alias %>()
44     {
45         return get<%= datatype %>(<%= table.Alias %>Schema.<%= column.Alias %>.getFieldName());
46     }
47 
48 
49     public void set<%= column.Alias %>(<%= datatype %> m_<%= column.Alias %>)
50     {
51         set<%= datatype %>(<%= table.Alias %>Schema.<%= column.Alias %>.getFieldName(), m_<%= column.Alias %>);
52     }
53  <%
54                 }
55  %>    
56  }<%
57         }
58 
59 
60         private string GetJavaType(IColumn column)
61         {
62                 string sqlServerType = column.DataTypeName;
63                 int charLength = column.CharacterMaxLength;
64 
65 
66                 switch (sqlServerType) 
67                 {
68                         case "bit":
69                                 return "Boolean";
70                         case "decimal":
71                         case "float":
72                         case "numeric":
73                         case "money":
74                         case "smallmoney":
75                         case "real":
76                                 return "Decimal";
77                         case "tinyint":
78                         case "smallint":
79                         case "int":
80                         case "bigint":
81                                 return "Integer";
82                         case "smalldatetime":
83                         case "datetime":
84                                 return "Timestamp";
85                         case "varchar":
86                         case "char":
87                         case "nvarchar":
88                         case "nchar":
89                         case "text":
90                                 if (charLength == 1)
91                                         return "Character";
92                                 else
93                                         return "String";
94                         default:
95                                 return "Object";
96                 }
97         }
98  }
99  %>

总结 

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

 

 

posted on 2014-06-01 10:34  yycGIS  阅读(418)  评论(0编辑  收藏  举报