重写代码生成器支持模板(多层架构,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 ...
随机推荐
- 使用VS2012调试ReactOS源码
目录 一 下载并安装VS2012 二 下载并安装WDK80 三 下载ReactOS0315源码 四 下载并安装RosBE211 五 用RosBE命令行编译ReactOS源码 六 用VS2012编译nt ...
- uva 10801(最短路)
题目大意: 有一层不超过100层的大楼, 有n个电梯,它们的速度都不同. 而且每个电梯只能到达指定的那些楼层,而且它们都有各自的速度(即上升一层或下降一层所用的时间). 如果一个人在某层走出电梯,要换 ...
- Windows Store App JavaScript 开发:简单对象绑定
简单对象绑定是一种基本的绑定类型,可以实现将一个对象中的数据绑定到HTML元素的属性.下面通过一个示例来演示如何使用HTML5和JavaScript开发一个实现简单对象绑定的Windows应用商店应用 ...
- css3过渡
语法格式: transition:属性名 完成时间 速度曲线 何时开始 transition:width 2s ease-in 3s: width 2s 整个过渡效果持续的时间 ease-in 指定了 ...
- Handle机制的原理
Android提供了Handle和Looper来满足线程间的通信.Handle先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(Message Exchange). 1.Looper: ...
- The connection to adb is down, and a severe error has occured.问题解决方法小结
遇到了几次这个问题:The connection to adb is down, and a severe error has occured. You must restart adb and Ec ...
- Error Domain=ASIHTTPRequestErrorDomain Code=8 "Failed to move file from"xxx/xxx"to"xxx/xxx"
今天真的好高兴呀 我解决了一个折磨了我一周的问题,真的是激动地要哭出来了,为了这个问题,我嘴也烂了,头发抓了一地啊.虽然解决方法,最后还是展现出了“百度”的伟大,但是我还是很开心,在这里我展示一下我的 ...
- JavaScript封装
js封装就是把使用方式简单化,内部逻辑和使用解耦.使用人员知道参数和返回值就可以了,其他不用使用人员设置. 封装就是将属性,方法,字段等封装成类. JavaScript封装方法 1,函数方式 func ...
- thymeleaf常用标签
1. th:checked ,th:selected标签<input type="radio" value="M" name="gender&q ...
- Android Bitmap Drawable 常用摘要
1.缩放 public Bitmap scalingBitmap(Bitmap bitmap, int newW, int newH) { int w = bitmap.getWidth(); int ...