这一个星期都在与代码生成器在奋战。
一开始,打算采用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());
// }
}
这是我反编译后的代码,边窗体都做好了。方便大家学习。
如果有人认为我冒犯了他的权益,就联系我。
等了半天,还没出天,哪天出来,我把链接放在这里。
代码下载:
CodeGenerator
http://download.csdn.net/detail/haoyujie/7215131
另外,请CSDN的编辑们放心,我所反编译的代码,原作者是提供原码的。
只是现在找不到原码了。所以,我这也不算什么过分。