利用CodeSmith在自己的工程中动态生成代码


这一个星期都在与代码生成器在奋战。

一开始,打算采用T4模板引挚。经过两天研究,发现困难很大。T4的设计,是与IDE绑在一起,而且每个visual studio版本,绑定越来越紧,越来越不兼容。

所以,还是打算采用CodeSmith.

一年多没用CodeSmith(原来也不会用),好不容易找到安装包还有一个重要的示例:


Code Generator using CodeSmith Api


http://www.codeproject.com/Articles/17065/Code-Generator-using-CodeSmith-Api


这个示例,比较清楚地写出了如何调用CodeSmith API,通过模板,生成代码:


但是,这个作者比较小气,没有公开原码。我也不清楚为什么,可能也有自己的原因。


所以,我反编译过了,找到了代码:


            CodeTemplateCompiler compiler;
            GenericProperty property = (GenericProperty) this.properties.GetProperty("Template Path", "Paths");
            GenericProperty property2 = (GenericProperty) this.properties.GetProperty("Code Path", "Paths");
            GenericProperty property1 = (GenericProperty) this.properties.GetProperty("SourceTable", "Database");
            GenericProperty property3 = (GenericProperty) this.properties.GetProperty("IncludeDelete", "StoreProcedure Options");
            GenericProperty property4 = (GenericProperty) this.properties.GetProperty("IncludeDrop", "StoreProcedure Options");
            GenericProperty property5 = (GenericProperty) this.properties.GetProperty("IncludeInsert", "StoreProcedure Options");
            GenericProperty property6 = (GenericProperty) this.properties.GetProperty("IncludeUpdate", "StoreProcedure Options");
            GenericProperty property7 = (GenericProperty) this.properties.GetProperty("IncludeGet", "StoreProcedure Options");
            GenericProperty property8 = (GenericProperty) this.properties.GetProperty("IncludeGetList", "StoreProcedure Options");
            GenericProperty property9 = (GenericProperty) this.properties.GetProperty("DeletePrefix", "StoreProcedure Style");
            GenericProperty property10 = (GenericProperty) this.properties.GetProperty("InsertPrefix", "StoreProcedure Style");
            GenericProperty property11 = (GenericProperty) this.properties.GetProperty("SelectPrefix", "StoreProcedure Style");
            GenericProperty property12 = (GenericProperty) this.properties.GetProperty("UpdatePrefix", "StoreProcedure Style");
            GenericProperty property15 = (GenericProperty) this.properties.GetProperty("Entire DataBase", "Database");
            GenericProperty property13 = (GenericProperty) this.properties.GetProperty("NameSpace", "NameSpace");
            GenericProperty property14 = (GenericProperty) this.properties.GetProperty("DotNet Version", "Version");
            if (!this.rbDatabase.Checked)
            {
                try
                {
                    this.timePB.Interval = 100;
                    this.timePB.Start();
                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\Entity.cst");
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template = compiler.CreateInstance();
                        DatabaseSchema schema = new DatabaseSchema(new SqlSchemaProvider(), "Server=" + this.cbServer.SelectedItem.ToString() + ";Database=" + this.dbName.SelectedItem.ToString() + ";uid=" + this.tbUserid.Text + ";pwd=" + this.tbPwd.Text);
                        TableSchema schema2 = schema.Tables[this.tbName.SelectedItem.ToString()];
                        template.SetProperty("NameSpace", property13.Value.ToString());
                        template.SetProperty("SourceTable", schema2);
                        template.RenderToFile(property2.Value.ToString() + @"\Entity\" + schema2.Name + ".cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\EntityBase.cst");
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template2 = compiler.CreateInstance();
                        DatabaseSchema schema3 = new DatabaseSchema(new SqlSchemaProvider(), "Server=" + this.cbServer.SelectedItem.ToString() + ";Database=" + this.dbName.SelectedItem.ToString() + ";uid=" + this.tbUserid.Text + ";pwd=" + this.tbPwd.Text);
                        TableSchema schema4 = schema3.Tables[this.tbName.SelectedItem.ToString()];
                        template2.SetProperty("NameSpace", property13.Value.ToString());
                        template2.SetProperty("SourceTable", schema4);
                        template2.RenderToFile(property2.Value.ToString() + @"\Entity\Base\" + schema4.Name + "Base.cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\DataProvider.cst");
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template3 = compiler.CreateInstance();
                        DatabaseSchema schema5 = new DatabaseSchema(new SqlSchemaProvider(), "Server=" + this.cbServer.SelectedItem.ToString() + ";Database=" + this.dbName.SelectedItem.ToString() + ";uid=" + this.tbUserid.Text + ";pwd=" + this.tbPwd.Text);
                        TableSchema schema6 = schema5.Tables[this.tbName.SelectedItem.ToString()];
                        template3.SetProperty("NameSpace", property13.Value.ToString());
                        template3.SetProperty("SourceTable", schema6);
                        template3.RenderToFile(property2.Value.ToString() + @"\Entity\" + schema6.Name + "DataProvider.cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    if (property14.Value.Equals("2003"))
                    {
                        compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\DataProviderBase1.cst");
                    }
                    else
                    {
                        compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\DataProviderBase.cst");
                    }
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template4 = compiler.CreateInstance();
                        DatabaseSchema schema7 = new DatabaseSchema(new SqlSchemaProvider(), "Server=" + this.cbServer.SelectedItem.ToString() + ";Database=" + this.dbName.SelectedItem.ToString() + ";uid=" + this.tbUserid.Text + ";pwd=" + this.tbPwd.Text);
                        TableSchema schema8 = schema7.Tables[this.tbName.SelectedItem.ToString()];
                        template4.SetProperty("NameSpace", property13.Value.ToString());
                        template4.SetProperty("SourceTable", schema8);
                        template4.RenderToFile(property2.Value.ToString() + @"\Entity\Base\" + schema8.Name + "DataProviderBase.cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\EntityControl.cst");
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template5 = compiler.CreateInstance();
                        DatabaseSchema schema9 = new DatabaseSchema(new SqlSchemaProvider(), "Server=" + this.cbServer.SelectedItem.ToString() + ";Database=" + this.dbName.SelectedItem.ToString() + ";uid=" + this.tbUserid.Text + ";pwd=" + this.tbPwd.Text);
                        TableSchema schema10 = schema9.Tables[this.tbName.SelectedItem.ToString()];
                        template5.SetProperty("NameSpace", property13.Value.ToString());
                        template5.SetProperty("SourceTable", schema10);
                        template5.RenderToFile(property2.Value.ToString() + @"\Entity\" + schema10.Name + "Control.cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    if (property14.Value.Equals("2003"))
                    {
                        compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\EntityControlBase1.cst");
                    }
                    else
                    {
                        compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\EntityControlBase.cst");
                    }
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template6 = compiler.CreateInstance();
                        DatabaseSchema schema11 = new DatabaseSchema(new SqlSchemaProvider(), "Server=" + this.cbServer.SelectedItem.ToString() + ";Database=" + this.dbName.SelectedItem.ToString() + ";uid=" + this.tbUserid.Text + ";pwd=" + this.tbPwd.Text);
                        TableSchema schema12 = schema11.Tables[this.tbName.SelectedItem.ToString()];
                        template6.SetProperty("NameSpace", property13.Value.ToString());
                        template6.SetProperty("SourceTable", schema12);
                        template6.RenderToFile(property2.Value.ToString() + @"\Entity\Base\" + schema12.Name + "ControlBase.cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\StoredProcedures.cst");
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template7 = compiler.CreateInstance();
                        DatabaseSchema schema13 = new DatabaseSchema(new SqlSchemaProvider(), "Server=" + this.cbServer.SelectedItem.ToString() + ";Database=" + this.dbName.SelectedItem.ToString() + ";uid=" + this.tbUserid.Text + ";pwd=" + this.tbPwd.Text);
                        TableSchema schema14 = schema13.Tables[this.tbName.SelectedItem.ToString()];
                        template7.SetProperty("SourceTable", schema14);
                        template7.SetProperty("IncludeDelete", property3.Value.ToString());
                        template7.SetProperty("IncludeDrop", property4.Value.ToString());
                        template7.SetProperty("IncludeInsert", property5.Value.ToString());
                        template7.SetProperty("IncludeUpdate", property6.Value.ToString());
                        template7.SetProperty("IncludeGet", property7.Value.ToString());
                        template7.SetProperty("IncludeGetList", property8.Value.ToString());
                        template7.SetProperty("DeletePrefix", property9.Value.ToString());
                        template7.SetProperty("InsertPrefix", property10.Value.ToString());
                        template7.SetProperty("SelectPrefix", property11.Value.ToString());
                        template7.SetProperty("UpdatePrefix", property12.Value.ToString());
                        template7.RenderToFile(property2.Value.ToString() + @"\Entity\Sp\" + schema14.Name + "StoredProcedures.sql", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\GenericList.cst");
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template8 = compiler.CreateInstance();
                        template8.SetProperty("NameSpace", property13.Value.ToString());
                        template8.RenderToFile(property2.Value.ToString() + @"\Entity\GenericList.cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\CBO.cst");
                    compiler.Compile();
                    if (compiler.Errors.Count == 0)
                    {
                        CodeTemplate template9 = compiler.CreateInstance();
                        template9.SetProperty("NameSpace", property13.Value.ToString());
                        template9.RenderToFile(property2.Value.ToString() + @"\Entity\CBO.cs", true);
                    }
                    else if (compiler.Errors.Count > 0)
                    {
                        MessageBox.Show(compiler.Errors.ToString());
                    }
                    this.timePB.Stop();
                    this.ProgressBar1.Value = 0;
                    ConfirmMsg msg = new ConfirmMsg();
                    msg.linkLabel1.Text = property2.Value.ToString() + @"\Entity";
                    msg.linkLabel1.Links.Add(0, 100, property2.Value.ToString() + @"\Entity");
                    msg.Show();
                }
                catch (Exception exception)
                {
                    this.timePB.Stop();
                    this.ProgressBar1.Value = 0;
                    MessageBox.Show(exception.Message.ToString());
                }
            }

最关键就是这两句:


                    compiler = new CodeTemplateCompiler(property.Value.ToString() + @"\Entity.cst");
                    compiler.Compile();

然而,意想不到的事情发生了。

没想到CodeSmith公司,更是小气,CodeSmith.Engine.dll 竞然,需要license才可以被调用,我了个去,有这么黑的吗?

原来用的是4.1.1,然后到网上,找了一天多,终于找到5.3有破解的CodeSmith.Engine.dll库。

http://download.csdn.net/detail/meanshe/3949350

Code Smith v5.3.3 破解补丁

真是救了我的工作啊。

感谢上帝。


否则,我可能就得自己亲自动手来破解了。可能又得几天。




另外,我的代码里,有两处注掉了,如果你已有数据库,想让界面每次弹出,都事先写好信息,就把那些代码反注掉:


第一处:

        public CodeGenerator()
        {
            this.InitializeComponent();
            this.GetServerName();
            this.comboBox1.SelectedIndex = 1;

            //如果不想每次都输入用户密码,就打开这些注释
            //tbUserid.Text = "sa";
            //tbPwd.Text = "123456";  //haoyujie
        }


第二处:


        private void CodeGenerator_Load(object sender, EventArgs e)
        {
            this.properties = new GenericPropertyCollection_CustomTypeDescriptor();
            this.properties.AddProperty(new GenericProperty("NameSpace", "PIMail", "NameSpace", "This is the NameSpace of the project", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("Entire DataBase", "True", "DataBase", "Is Code generated for whole database or not", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("IncludeDelete", "True", "StoreProcedure Options", "Is Delete StoreProcedure Included or not", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("IncludeDrop", "True", "StoreProcedure Options", "Is Drop Script Included or not", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("IncludeInsert", "True", "StoreProcedure Options", "Is Insert Script Included or not", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("IncludeUpdate", "True", "StoreProcedure Options", "Is Update Script Included or not", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("IncludeGet", "True", "StoreProcedure Options", "Is Get Script Included or not", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("IncludeGetList", "True", "StoreProcedure Options", "Is GetList Script Included or not", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("DeletePrefix", "Delete", "StoreProcedure Style", "the prefix for delete store procedure", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("InsertPrefix", "Add", "StoreProcedure Style", "the prefix for Add store procedure", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("SelectPrefix", "Select", "StoreProcedure Style", "the prefix for Select store procedure", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("UpdatePrefix", "Update", "StoreProcedure Style", "the prefix for Update store procedure", new Attribute[0]));
            this.properties.AddProperty(new GenericProperty("DotNet Version", "2003", "Version", "The DotNet Version ", new Attribute[0]));
            this.propertyGrid1.SelectedObject = this.properties;
            this.propertyGrid1.Refresh();


            //如果不想每次都输入用户密码,就打开这些注释
            //haoyujie
         //   this.GetConnection();
   

         //   string curDatabaseName = "AutoPack";
         //this.dbName.SelectedText = curDatabaseName;
         //   if (!this.Added)   //标记属性框里,是否有
         //   {
         //       AddDatabaseName(curDatabaseName);
         //   }
         //   else
         //   {
         //       ModifyDatabaseName(curDatabaseName);
         //   }
         //   this.dbName.SelectedIndex = 0;
         //   this.dbtoolStripComboBox2.SelectedIndex = this.dbName.SelectedIndex;

         //   this.rbDatabase.Checked = false;
         //   this.rbTable.Checked = true;

         //   tbName.SelectedItem = "TBL_TREE_HIERARCHY";
         //   //////////////////////////////////////////////////////////////////////////
         //   this.tbTemplate.Text = "E:\\tmp\\Final_Templates";

         //   this.properties.AddProperty(new GenericProperty("Template Path", this.tbTemplate.Text, "Paths", "The path where the templates are place", new Attribute[0]));
         //   this.propertyGrid1.Refresh();
         //   this.tempathAdded = true;
         //   //////////////////////////////////////////////////////////////////////////
         //   this.tbCode.Text = "E:\\tmp\\tmpcodeout";

         //   this.properties.AddProperty(new GenericProperty("Code Path", this.tbCode.Text, "Paths", "The path where the templates are place", new Attribute[0]));
         //   this.propertyGrid1.Refresh();
         //   this.codepathAdded = true;

         //   try
         //   {
         //       DirectoryInfo info = new DirectoryInfo(this.tbCode.Text);
         //       info.CreateSubdirectory("Entity");
         //       info.CreateSubdirectory(@"Entity\Base");
         //       info.CreateSubdirectory(@"Entity\Sp");
         //   }
         //   catch (Exception exception)
         //   {
         //       MessageBox.Show(exception.Message.ToString());
         //   }

        }

利用CodeSmith在自己的工程中动态生成代码_第1张图片

这是我反编译后的代码,边窗体都做好了。方便大家学习。

如果有人认为我冒犯了他的权益,就联系我。


等了半天,还没出天,哪天出来,我把链接放在这里。

代码下载:

CodeGenerator

 

http://download.csdn.net/detail/haoyujie/7215131

 

另外,请CSDN的编辑们放心,我所反编译的代码,原作者是提供原码的。

只是现在找不到原码了。所以,我这也不算什么过分。

你可能感兴趣的:(C#,templates,codesmith)