重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译
多年前用过李天平前辈的,自己改过,后来李老师做动软了,不给源码,修改不是很方便。加上我目前需要转java方向,于是决定自己搞。到目前为止花了整整一个星期了,看看目前的成果。






最后是代码工程文件,用c#开发的,IDE是vs2010

为了实现最大的模板自由,设计了专有的模板语法。基于C#,但是已经做到尽量简化,对有一点开发经验的同行应该是很好上手的。
目前c#的代码模板已经做了一些通用样例,接下来做java的开发代码模板。
总之,为了提高效率,并且规范项目团队成员的代码书写。
下面把核心的代码两个类文件贴出来,分别是动态编译和模板解析
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using System.Reflection; namespace CodeMaker.Engine
{
public class Compiler
{
/// <summary>
/// 普通代码编译执行出字符串
/// </summary>
/// <param name="strCode"></param>
/// <returns></returns>
public static string DoCompile(string strCode)
{ StringBuilder strResults = new StringBuilder(); CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); //CompilerParameters 编译参数
CompilerParameters objCompilerParameters = new CompilerParameters();
objCompilerParameters.ReferencedAssemblies.Add("System.dll");
objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll");
objCompilerParameters.ReferencedAssemblies.Add("System.Data.dll");
objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.BLL.dll");
objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.DALFactory.dll");
objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.IDAL.dll");
objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.Model.dll");
objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.MySqlDAL.dll");
objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.SqlDAL.dll");
objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.Engine.dll");
objCompilerParameters.GenerateExecutable = false;
objCompilerParameters.GenerateInMemory = true; // CompilerResults
CompilerResults cr = provider.CompileAssemblyFromSource(objCompilerParameters, strCode); if (cr.Errors.HasErrors)
{
Console.WriteLine("编译错误:");
foreach (CompilerError err in cr.Errors)
{
strResults.Append(err.ErrorText);
strResults.Append(Environment.NewLine);
strResults.Append(err.Line);
strResults.Append(Environment.NewLine);
strResults.Append(err.ToString());
strResults.Append(Environment.NewLine); }
}
else
{
// 通过反射,调用OutPut的输出方法
Assembly objAssembly = cr.CompiledAssembly;
object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.CodeGenerate");
MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut"); strResults.Append(objMI.Invoke(objHelloWorld, null));
strResults.Append(Environment.NewLine); } return strResults.ToString();
} public static string DoCodeMakerCompile(string strDBType,string DALAssemblyPath, string strDataBase,string strTableName, string strEntityName,string strCode)
{ StringBuilder sb = new StringBuilder();
//加上要编译部分代码的头部和尾部
//头部
sb.Append("using System;");
sb.Append("using System.Data;");
sb.Append("using System.Text;");
sb.Append("using System.Linq;");
sb.Append("using System.Globalization;");
sb.Append("using System.Collections.Generic;");
sb.Append("using CodeMaker.Model;");
sb.Append("using CodeMaker.BLL;");
sb.Append("using CodeMaker.Engine;");
sb.Append("namespace DynamicCodeGenerate");
sb.Append("{"); sb.Append(" public class CodeGenerate");
sb.Append(" {");
sb.Append(" public string OutPut()");
sb.Append(" {"); //读取数据实体的属性的代码段
sb.Append(GetEntity(strDBType, DALAssemblyPath, strDataBase, strTableName, strEntityName)); sb.Append(strCode); //返回值,字符串
sb.Append(" return s.ToString(); ");
sb.Append(" }");
//fOutPut方法结束
//首字母大写方法
sb.Append(" public string ToTitleCase(string str)");
sb.Append(" {");
sb.Append(" return str.Substring(0,1).ToUpper()+str.Substring(1);");
sb.Append(" }");
//首字母小写方法
sb.Append(" public string ToLowerCase(string str)");
sb.Append(" {");
sb.Append(" return str.Substring(0,1).ToLower()+str.Substring(1);");
sb.Append(" }"); sb.Append(" }");
sb.Append("}"); return DoCompile(sb.ToString());
} private static string GetEntity(string strDBType, string DALAssemblyPath, string strDataBase, string strTableName, string strEntityName)
{
StringBuilder sb = new StringBuilder();
sb.Append("CodeMaker.BLL.EntityBLL bll = new CodeMaker.BLL.EntityBLL(\"" + DALAssemblyPath + "\");");
sb.Append("IList<CodeMaker.Model.Entity> es = bll.GetEntityList(\"" + strDataBase + "\", \"" + strTableName + "\");");
sb.Append("string EntityName=\"" + strEntityName + "\";");//实体名,供模板中的代码段使用
sb.Append("string TableName=\"" + strTableName + "\";");//表名,供模板中的代码段使用
sb.Append("string DBType=\"" + strDBType + "\";");//数据库组件,判断数据库种类SQLSERVER,MYSQL,供模板中的代码段使用
sb.Append("string TablePri=(es.Where(x=>x.IsPri==\"YES\").Count()>0)?es.Where(x=>x.IsPri==\"YES\").ToList()[0].ColumnName:\"\";");//表的主键列 名称
sb.Append("string TablePriDataType=(es.Where(x=>x.IsPri==\"YES\").Count()>0)?CodeAnalysis.ToDataTypeFormat(es.Where(x=>x.IsPri==\"YES\").ToList()[0].DataType,DBType):\"\";");//表的主键列 数据类型
return sb.ToString(); } public static string GenerateCode()
{
return "";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; namespace CodeMaker.Engine
{
public class CodeAnalysis
{
public static string Hello()
{
return "Hello";
} public static string ToCSharpCode(string strContent)
{
StringBuilder sb = new StringBuilder();
//需要逐行解析
string[] ss = strContent.Split('\n');
string strT=string.Empty;
if (ss.Length > )
{
sb.Append("StringBuilder s = new StringBuilder();");//如果行数不为0,则需要声明字符串拼接
sb.Append(System.Environment.NewLine);
}
for (int i = ; i < ss.Length; i++)
{
//处理字符串行
sb.Append(DealCode(ss[i]));
sb.Append(System.Environment.NewLine); } return sb.ToString();
} /// <summary>
/// 单行字符串处理
/// </summary>
/// <param name="strLine"></param>
/// <returns></returns>
private static string DealCode(string strLine)
{
//判断当该行是无特殊代码行。特殊代码(<-$、$->) strLine = Regex.Replace(strLine, @"[\r\n]", ""); //替换掉常量中的换行符 if (strLine.Contains("<-$") && strLine.Contains("$->"))
{
//有整行特殊代码段
//strLine = strLine.Replace("\"", "\\\"");
strLine = strLine.Replace("<-$", "");
strLine = strLine.Replace("$->", ""); //strLine += "s.Append(System.Environment.NewLine);";
}
else if (strLine.Contains("<+$") && strLine.Contains("$+>"))
{
//有变量取值代码段
strLine = strLine.Replace("\"", "\\\"");
strLine = "\""+strLine+"\\n\"";//前后先加引号,后面加个换行
strLine = strLine.Replace("<+$", "\"+");
strLine = strLine.Replace("$+>", "+\""); strLine = "s.Append("+ strLine +");";
}
else
{
//不是特殊代码行
//strLine = "s.Append(\"" + strLine + "\"); s.Append(System.Environment.NewLine);" ;
strLine = strLine.Replace("\"", "\\\"");
strLine = "s.Append(\"" + strLine + "\\n\");";
} return strLine;
} #region 供动态编译的代码段中调用的静态方法 /// <summary>
/// 数据库字段数据类型 转为 java语言中的数据类型
/// </summary>
/// <param name="strDBColumnType">数据库字段数据类型</param>
/// <param name="strDBType">数据库MYSQL SQLSERVER</param>
/// <returns></returns>
public static string ToJavaDataType(string strDBColumnType, string strDBType)
{
string strT = string.Empty; //根据strDBType 判断数据库是什么,然后转换为程序语言中的数据类型
switch (strDBType)
{
case "SQLSERVER":
var stringwords = new string[]{"char","varchar","text","nchar","nvarchar","ntext"};
var intwords = new string[]{"int","smallint","tinyint"};
var boolwords = new string[] { "bit"};
var longwords = new string[] { "bigint"};
var decimalwords = new string[] { "numeric", "decimal", "money","smallmoney","float","real" };
var datewords = new string[] { "datetime", "smalldatetime" };
if (stringwords.Contains(strDBColumnType.ToLower()))
{
strT="String";
}
else if (intwords.Contains(strDBColumnType.ToLower()))
{
strT = "int";
}
else if (longwords.Contains(strDBColumnType.ToLower()))
{
strT = "long";
}
else if (boolwords.Contains(strDBColumnType.ToLower()))
{
strT = "boolean";
}
else if (decimalwords.Contains(strDBColumnType.ToLower()))
{
strT = "decimal";
}
else if (datewords.Contains(strDBColumnType.ToLower()))
{
strT = "DateTime";
}
else
{
strT = "String";
} break; case "MYSQL":
var stringwords1 = new string[]{"char","varchar","text","tinytext","mediumtext","longtext"};
var intwords1 = new string[]{"smallint","tinyint","mediumint"};
var boolwords1 = new string[] { "bit"};
var longwords1 = new string[] { "int,bigint", "integer" };
var decimalwords1 = new string[] { "float", "decimal", "double" };
var datewords1 = new string[] { "datetime", "date" };
if (stringwords1.Contains(strDBColumnType.ToLower()))
{
strT = "String";
}
else if (intwords1.Contains(strDBColumnType.ToLower()))
{
strT = "int";
}
else if (longwords1.Contains(strDBColumnType.ToLower()))
{
strT = "long";
}
else if (boolwords1.Contains(strDBColumnType.ToLower()))
{
strT = "boolean";
}
else if (decimalwords1.Contains(strDBColumnType.ToLower()))
{
strT = "decimal";
}
else if (datewords1.Contains(strDBColumnType.ToLower()))
{
strT = "DateTime";
}
else
{
strT = "String";
} break; default:
break;
} return strT;
} /// <summary>
/// 数据库字段数据类型 转为 c# 语言中的数据类型
/// </summary>
/// <param name="strDBColumnType">数据库字段数据类型</param>
/// <param name="strDBType">数据库MYSQL SQLSERVER</param>
/// <returns></returns>
public static string ToCSDataType(string strDBColumnType, string strDBType)
{
string strT = string.Empty; //根据strDBType 判断数据库是什么,然后转换为程序语言中的数据类型
switch (strDBType)
{
case "SQLSERVER":
var stringwords = new string[]{"char","varchar","text","nchar","nvarchar","ntext"};
var intwords = new string[]{"int","smallint","tinyint"};
var boolwords = new string[] { "bit"};
var longwords = new string[] { "bigint"};
var decimalwords = new string[] { "numeric", "decimal", "money","smallmoney","float","real" };
var datewords = new string[] { "datetime", "smalldatetime" };
if (stringwords.Contains(strDBColumnType.ToLower()))
{
strT="string";
}
else if (intwords.Contains(strDBColumnType.ToLower()))
{
strT = "int";
}
else if (longwords.Contains(strDBColumnType.ToLower()))
{
strT = "long";
}
else if (boolwords.Contains(strDBColumnType.ToLower()))
{
strT = "bool";
}
else if (decimalwords.Contains(strDBColumnType.ToLower()))
{
strT = "decimal";
}
else if (datewords.Contains(strDBColumnType.ToLower()))
{
strT = "DateTime";
}
else
{
strT = "string";
} break; case "MYSQL":
var stringwords1 = new string[]{"char","varchar","text","tinytext","mediumtext","longtext"};
var intwords1 = new string[]{"smallint","tinyint","mediumint"};
var boolwords1 = new string[] { "bit"};
var longwords1 = new string[] { "int,bigint", "integer" };
var decimalwords1 = new string[] { "float", "decimal", "double" };
var datewords1 = new string[] { "datetime", "date" };
if (stringwords1.Contains(strDBColumnType.ToLower()))
{
strT="string";
}
else if (intwords1.Contains(strDBColumnType.ToLower()))
{
strT = "int";
}
else if (longwords1.Contains(strDBColumnType.ToLower()))
{
strT = "long";
}
else if (boolwords1.Contains(strDBColumnType.ToLower()))
{
strT = "bool";
}
else if (decimalwords1.Contains(strDBColumnType.ToLower()))
{
strT = "decimal";
}
else if (datewords1.Contains(strDBColumnType.ToLower()))
{
strT = "DateTime";
}
else
{
strT = "string";
} break; default:
break;
} return strT;
} /// <summary>
/// 把小写的sqlserver数据库中的数据类型转为sqlserver参数格式,例如 SqlDbType.VarChar
/// </summary>
/// <param name="strDataType"></param>
/// <param name="strDBType">数据库MYSQL SQLSERVER</param>
/// <returns></returns>
public static string ToDataTypeFormat(string strDataType,string strDBType)
{
string strT = string.Empty;
switch (strDataType.ToLower())
{
case "int":
strT = "Int";
break;
case "varchar":
strT = "VarChar";
break;
case "char":
strT = "Char";
break;
case "bigint":
strT = "BigInt";
break;
case "nvarchar":
strT = "NVarChar";
break;
case "datetime":
strT = "DateTime";
break;
case "smalldatetime":
strT = "SmallDateTime";
break;
case "bit":
strT = "Bit";
break;
case "text":
strT = "Text"; break;
case "decimal":
strT = "Decimal";
break;
case "ntext":
strT = "NText";
break;
default:
strT = "VarChar";
break;
} return strT;
} /// <summary>
/// 获取数据类型或控件的简写,用于前缀命名
/// </summary>
/// <param name="strLongName"></param>
/// <returns></returns>
public static string ToNameFormat(string strLongName)
{
string strT = string.Empty;
switch (strLongName.ToLower())
{
case "int":
strT = "int";
break;
case "string":
strT = "str";
break;
case "char":
strT = "ch";
break;
case "long":
strT = "long";
break;
case "float":
strT = "float";
break;
case "datetime":
strT = "date";
break;
case "double":
strT = "double";
break;
case "bool":
strT = "Is";
break;
case "decimal":
strT = "dec";
break;
case "boolean":
strT = "Is";
break;
default:
strT = "x";
break;
} return strT;
}
#endregion
}
}
--------------------------------------------------------------------------
有位博友提到过T4模板,我也看了一点点,但是我考虑的是不单单生成c#代码,目标代码还要java,因为目前正在转java方向。为了灵活性,我觉得自己定义规则比较放心,也许这个想法不成熟,但是先试试吧
下载链接
http://www.cnblogs.com/allanyang/p/4702467.html
重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译的更多相关文章
- 多层架构+MVC+EF+AUTOFAC+AUTOMAPPER
最近使用ligerui搭建了一个简单的教务管理demo,将重要的地方记录,也希望能帮到有这方面需要园友. 一.目录 1.多层架构+MVC+EF+AUTOFAC+AUTOMAPPER: 2.MVC中验证 ...
- MVC 5 Scaffolding多层架构代码生成向导开源项目
asp.net MVC 5 Scaffolding多层架构代码生成向导开源项目(邀请你的参与) Visual Studio.net 2013 asp.net MVC 5 Scaffolding代码 ...
- 转载Mvc的多层架构
Mvc的多层架构 分享一个Mvc的多层架构,欢迎大家拍砖斧正 多层架构是什么? 多层架构是开发人员在开发过程当中面对复杂且易变的需求采取的一种以隔离控制为主的应对策略,关于多层架构的标准,我认为有 ...
- ASP.NET MVC 扩展自定义视图引擎支持多模板&动态换肤skins机制
ASP.NET mvc的razor视图引擎是一个非常好的.NET MVC 框架内置的视图引擎.一般情况我们使用.NET MVC框架为我们提供的这个Razor视图引擎就足够了.但是有时我们想在我们的 ...
- 分享一个MVC的多层架构,欢迎大家拍砖斧正
如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 多层架构是开发人员在开发过程当中面对复杂且易变的需求采取的一种以隔离控制为主的应对策 ...
- Mvc的多层架构
分享一个Mvc的多层架构,欢迎大家拍砖斧正 多层架构是什么? 多层架构是开发人员在开发过程当中面对复杂且易变的需求采取的一种以隔离控制为主的应对策略,关于多层架构的标准,我认为有一句话是比较有代表 ...
- 如何让MVC和多层架构和谐并存(一)
MVC的架构和多层架构,在ORM框架上是不兼容的.MVC的数据库操作需要通过实体框架Entity Framework,多层的数据库操作需要通过DAL层.我们最近刚完成的项目,实现了MVC和多层的并存, ...
- 用于构建 RESTful Web 服务的多层架构
作者:Bruce Sun, Java 架构师, IBM 出处:http://www.ibm.com/developerworks/cn/web/wa-aj-multitier/ 用于构建 RESTfu ...
- .NET跨平台之mac 下vs code 多层架构编程
合肥程序员群:49313181. 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入,申请备注填写姓名+技术+工作年限) Q Q:408365330 E-Mail:eg ...
随机推荐
- ElasticSearch配置说明
配置文件位于%ES_HOME%/config/elasticsearch.yml文件中. cluster.name: elasticsearch 配置集群名称,默认elasticsearch node ...
- 编译MVC解决方案老出现这个问题的原因
Server Error in '/' Application. The view at '~/Views/Home/Index.cshtml' must derive from WebViewPag ...
- JS数组常用函数以及查找数组中是否有重复元素的三种常用方法
阅读目录: DS01:常用的查找数组中是否有重复元素的三种方法 DS02:常用的JS函数集锦 DS01.常用的查找数组中是否有重复元素的三种方法 1. var ary = new Array(&qu ...
- Java面试常见各种概念区别比较
Hashtable 和 HashMap之间的区别 Hashtable是继承了Dictionary,是线程安全的.HashMap实现了Map接口,不是线程安全的.HashMap是Hashtable的轻量 ...
- 调整ESX的VMFS磁盘格式的块大小,让单个虚拟磁盘支持更大容量
调整ESX的VMFS磁盘格式的块大小,让单个虚拟磁盘支持更大容量 前因:客户搭建了VMware ESX企业版的测试平台:有一天接到一个需求,是测试数据库的,需要一个300G的磁盘. 解决过程: 1.按 ...
- IHttpHandler防止图片链接被盗用
public class JpegHandler : IHttpHandler { public bool IsReusable { get { return true; } } public voi ...
- Android中的Service小结
简介 Service适合执行不需要和用户交互,而且长期运行的任务.即使程序被切换回后台,服务仍然可以正常运行.Service并不自动开启线程,默认运行在主线程中. Service中需要重载的函数 on ...
- Android 设置ListView当前显示的item
项目中可能会有这种需求:动态设置ListView显示的item 这种需求可能会出现在不同的情况下,有的是打开页面就要显示在特定的位置,也有的是浏览列表时实时更新数据并且改变了集合中数据,或者是某种条件 ...
- K2新网站(官网和BPM社区)正式上线了
K2新网站(官网和BPM社区)正式上线了 K2新网站(官网和BPM社区)正式上线了 K2新网站(官网和BPM社区)正式上线了 通常重要的事情要讲三遍, 官网:www.k2software.cn 社区: ...
- Copy page via powershell and not save as template 分类: Sharepoint 2015-07-16 16:39 4人阅读 评论(0) 收藏
By save as template informaton of the page get lost, e.g. permissions. To avoid this, use powershell ...