您的位置:首页 > 编程语言

代码自动生成工具MyGeneration之三

2008-09-10 19:21 746 查看
  接前面的文章继续。
  代码自动生成工具MyGeneration之二

  前面讲了MyGeneration的使用,以及如何自己写模板显示UI,现在开始讲如何将数据库的信息显示到UI上。
在MyGeneraion脚本系统中,有一个全局变量,叫做MyMeta,他是dbRoot类型的。通过这个全局变量,我们可以获得数据库相关的信息。这个变量在Interface Code 和Template Code中都可以使用。
  从上节代码来看,我们建立Form窗口的时候,就把这个变量给传给了Form窗口
  如下代码所示:
  MyForm form = new MyForm(MyMeta, input);
   那么dbRoot类型的MyMeta变量都有哪些功能,有哪些函数,属性可以使用呢?
我们可以查找帮助,通过MyGeneration菜单 “File – Help – MyMeta API Reference”可以打开其帮助,里面有dbRoot的详细介绍,如下图所示:



  大概看一下API,然后我们就可以修改我们的模板了,将其修改如下:

        private void Form1_Load(object sender, EventArgs e)
        {
            //获取数据库,传给ComboBox
            comboBox1.DataSource    = this.myMeta.Databases;
            //ComboBox显示数据库名
            this.comboBox1.DisplayMember = "Name";  
            
            if(this.myMeta.DefaultDatabase != null)
            {
                //选中默认的数据库
                this.comboBox1.SelectedIndex = this.comboBox1.FindStringExact(this.myMeta.DefaultDatabase.Name);
                //通过IDatabase 的Tables属性取得数据库里面所有的数据表
                //作为数据源传给ListBox
                this.listBox1.DataSource = this.myMeta.DefaultDatabase.Tables;
                //ListBox显示数据表的名字
                this.listBox1.DisplayMember = "Name";
            }   
        }
        

  就算没有注释,这代码也很好懂吧。
  呵呵,由此可见,我们可以通过MyMeta得到IDataBases,然后获得ITable,在通过ITable
获得数据表的信息……反正呢,照这条线找下去,基本上数据库里有哪些表,表里有哪些字段,有哪些存储过程,任何信息都可以很容易的得到。当然了,在自己写模板之前,最好先大概看一下“MyMeta API Reference”,这样就写模板就会更得心应手了。
  下面接下来看Form点击OK之后的代码吧
         private void button1_Click(object sender, EventArgs e)
        {
            IDatabase database = this.comboBox1.SelectedValue as IDatabase;
            ITable    table    = this.listBox1.SelectedValue as ITable;
            
            this.zeusInput["databaseName"] = database.Name;
            this.zeusInput["tableName"]    = table.Name;
            
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
  这段代码得重点讲一下了,因为Interface Code是关于UI的,那么UI执行完了之后,我们就需要用到Template Code了,那么Template Code和Interface Code是如何联系在一起的呢? 我们在Template Code里面如何知道Interface Code显示的UI中用户输入了什么,选择了什么?
  这用到了MyGeneration的一个非常重要的类IZeusInput。
  改接口的详细信息请看帮助 “File – help – Zeus API Reference”。
  在这里我们简单的把UI上选中的数据库的名字和数据表的名字存在了IZeusInput变量中。大家注意看下Form的IZeumInput是如何来的吧。
  这样,我们就完成了该模板的Interface Code的代码,最后形成的Interface Code就如下所示:
<%#REFERENCE System.Windows.Forms.dll, System.Drawing.dll %>
<%#NAMESPACE System.Windows.Forms, System.Drawing %>
public class GeneratedGui : DotNetScriptGui
{
    public GeneratedGui(ZeusContext context) : base(context) {}
    //-----------------------------------------
    // The User Interface Entry Point
    //-----------------------------------------
    public override void Setup()
    {
        // ** UNCOMMENT CODE BELOW TO SEE UI **
        //ui.Width  = 100;
        //ui.Height = 100;
        //GuiLabel lblDemo = ui.AddLabel("lblDemo", "Demo", "Demo Tooltip");
        //ui.ShowGui = true;
        Form1 form = new Form1(MyMeta, input); 
        if (form.ShowDialog() != DialogResult.OK) 
        {
            ui.IsCanceled = true;
        }
    }
}
    public class Form1:Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.comboBox1 = new System.Windows.Forms.ComboBox();
            this.listBox1 = new System.Windows.Forms.ListBox();
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // comboBox1
            // 
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.Location = new System.Drawing.Point(22, 24);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(233, 20);
            this.comboBox1.TabIndex = 0;
            this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
            // 
            // listBox1
            // 
            this.listBox1.FormattingEnabled = true;
            this.listBox1.ItemHeight = 12;
            this.listBox1.Location = new System.Drawing.Point(22, 50);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(233, 196);
            this.listBox1.TabIndex = 1;
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(180, 252);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 2;
            this.button1.Text = "OK";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 293);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.listBox1);
            this.Controls.Add(this.comboBox1);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.Text = "ZhouKai's BLL Class";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
        }
        #endregion
        private System.Windows.Forms.ComboBox comboBox1;
        private System.Windows.Forms.ListBox listBox1;
        private System.Windows.Forms.Button button1;
                
                
        private dbRoot myMeta;
        private IZeusInput zeusInput;
        public Form1(dbRoot myMeta, IZeusInput zeusInput)
        {
            this.myMeta    = myMeta;
            this.zeusInput = zeusInput;
            
            InitializeComponent();
        }   
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            IDatabase database = this.comboBox1.SelectedValue as IDatabase;
            if(database != null)
            {
                this.listBox1.DataSource = database.Tables;
                this.listBox1.DisplayMember = "Name";
            }   
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            //获取数据库,传给ComboBox
            comboBox1.DataSource    = this.myMeta.Databases;
            //ComboBox显示数据库名
            this.comboBox1.DisplayMember = "Name";  
            
            if(this.myMeta.DefaultDatabase != null)
            {
                //选中默认的数据库
                this.comboBox1.SelectedIndex = this.comboBox1.FindStringExact(this.myMeta.DefaultDatabase.Name);
                //通过IDatabase 的Tables属性取得数据库里面所有的数据表
                //作为数据源传给ListBox
                this.listBox1.DataSource = this.myMeta.DefaultDatabase.Tables;
                //ListBox显示数据表的名字
                this.listBox1.DisplayMember = "Name";
            }   
        }
        
         private void button1_Click(object sender, EventArgs e)
        {
            IDatabase database = this.comboBox1.SelectedValue as IDatabase;
            ITable    table    = this.listBox1.SelectedValue as ITable;
            
            this.zeusInput["databaseName"] = database.Name;
            this.zeusInput["tableName"]    = table.Name;
            
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
    }

  下面来看Template Code如何写吧。目前的模板默认的Template Code如下所示:

<%
public class GeneratedTemplate : DotNetScriptTemplate
{
    public GeneratedTemplate(ZeusContext context) : base(context) {}
    //---------------------------------------------------
    // Render() is where you want to write your logic    
    //---------------------------------------------------
    public override void Render()
    {
        %>
        You can toggle in out of script like this
        <%
        output.writeln("Hello world.");
    }
}
%>

  C# Template Code的语法和Asp的语法十分的类似<%=%>表示绑定某一个字段或属性
  <%%>表示脚本段,我们可以在这里写符合C#语法的任何语句
  其他的内容不进行解析直接用output写到最后的结果里

  修改Template Code,改成如下所示:
<%
public class GeneratedTemplate : DotNetScriptTemplate
{
    public GeneratedTemplate(ZeusContext context) : base(context) {}
    public override void Render()
    {
        //设置输出语言...
        MyMeta.Language = "C#";
        MyMeta.DbTarget = "SQLClient";
        //获得执行完UI后,我们说选中的数据库名,数据表名
        string databaseName = input["databaseName"].ToString();
        string tableName    = input["tableName"].ToString();
            
        IDatabase database = MyMeta.Databases[databaseName];
        //获得数据表的接口
        ITable table = database.Tables[tableName];
        
        %>
        
namespace BLL
{
    using System;
    using System.Data;
    
    using System.Collections;
    using System.Collections.Generic;
        
<%      
        //数据表的名称作为BLL类的类名
        output.writeln("    public partial class " + tableName );
        output.writeln("    {   ");
        
        //遍历数据表中所有字段    
        foreach (IColumn column in table.Columns)
        {
            //将字段名第一个字母转为小写
            string tmpColumnName = DnpUtils.SetCamelCase(column.Name);
            output.writeln("        private " + column.LanguageType + " _" + tmpColumnName + ";");
            output.writeln("        public " + column.LanguageType + " " + column.Name);
            output.writeln("        {");
            output.writeln("            get { return _" + tmpColumnName + ";    }");
            output.writeln("            set { _" + tmpColumnName + " = value;   }");
            output.writeln("        }");
            output.writeln("");     
        }   
        output.writeln("    }   ");     
        output.writeln("}");
    }
}
%>
  这代码也非常简单,基本不用解释都能看懂,不用几分钟就能自己写出来了。
  运行一下该模板,看下是不是类似有如下输出呢?
namespace BLL
{
    using System;
    using System.Data;
    
    public partial class User
    {   
        private int _id;
        public int ID
        {
            get { return _id;   }
            set { _id = value;  }
        }
        private string _userName;
        public string UserName
        {
            get { return _userName;     }
            set { _userName = value;    }
        }
    }   
}
  好了,最简单的一个生成BLL类的模板就完成了。
  本来还想写下如何用MyGeneration来生成执行存储过程的函数,如何用MyGeneration来生成测试存储过程函数的代码的。我觉得完成了这个模板,基本上就可以自己查找MyGeneration的帮助中的API完成这些了,应该不用继续下去了。
继续意淫一下,假如写数据库相关的程序,有了MyGeneration,我们的工作就简单多了,我们可以自己写模板,自动生成BLL类,DAL代码,自动生成测试代码……多棒啊

  转载请注明:本文来自
  http://blog.csdn.net/zxcred
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: