zoukankan      html  css  js  c++  java
  • 重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译

    多年前用过李天平前辈的,自己改过,后来李老师做动软了,不给源码,修改不是很方便。加上我目前需要转java方向,于是决定自己搞。到目前为止花了整整一个星期了,看看目前的成果。

    QQ图片20150729212121

    QQ截图20150729212205

    QQ截图20150729213325

    QQ截图20150729213412

    QQ截图20150729213436

    QQ截图20150729213529

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

    QQ截图20150729214011

    为了实现最大的模板自由,设计了专有的模板语法。基于C#,但是已经做到尽量简化,对有一点开发经验的同行应该是很好上手的。

    目前c#的代码模板已经做了一些通用样例,接下来做java的开发代码模板。

    总之,为了提高效率,并且规范项目团队成员的代码书写。

    下面把核心的代码两个类文件贴出来,分别是动态编译和模板解析

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.CodeDom.Compiler;
      6 using System.Reflection;
      7 
      8 namespace CodeMaker.Engine
      9 {
     10     public class Compiler
     11     {
     12         /// <summary>
     13         /// 普通代码编译执行出字符串
     14         /// </summary>
     15         /// <param name="strCode"></param>
     16         /// <returns></returns>
     17         public static string DoCompile(string strCode)
     18         {
     19             
     20             StringBuilder strResults = new StringBuilder();
     21 
     22             CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
     23 
     24             //CompilerParameters 编译参数
     25             CompilerParameters objCompilerParameters = new CompilerParameters();
     26             objCompilerParameters.ReferencedAssemblies.Add("System.dll");
     27             objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll");
     28             objCompilerParameters.ReferencedAssemblies.Add("System.Data.dll");
     29             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.BLL.dll");
     30             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.DALFactory.dll");
     31             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.IDAL.dll");
     32             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.Model.dll");
     33             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.MySqlDAL.dll");
     34             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.SqlDAL.dll");
     35             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.Engine.dll");
     36             objCompilerParameters.GenerateExecutable = false;
     37             objCompilerParameters.GenerateInMemory = true;
     38             
     39             // CompilerResults
     40             CompilerResults cr = provider.CompileAssemblyFromSource(objCompilerParameters, strCode);
     41 
     42             if (cr.Errors.HasErrors)
     43             {
     44                 Console.WriteLine("编译错误:");
     45                 foreach (CompilerError err in cr.Errors)
     46                 {
     47                     strResults.Append(err.ErrorText);
     48                     strResults.Append(Environment.NewLine);
     49                     strResults.Append(err.Line);
     50                     strResults.Append(Environment.NewLine);
     51                     strResults.Append(err.ToString());
     52                     strResults.Append(Environment.NewLine);
     53                 
     54                 }
     55             }
     56             else
     57             {
     58                 // 通过反射,调用OutPut的输出方法
     59                 Assembly objAssembly = cr.CompiledAssembly;
     60                 object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.CodeGenerate");
     61                 MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");
     62 
     63                 strResults.Append(objMI.Invoke(objHelloWorld, null));
     64                 strResults.Append(Environment.NewLine);
     65               
     66             }
     67             
     68             
     69             return strResults.ToString();
     70         }
     71 
     72         public static string DoCodeMakerCompile(string strDBType,string DALAssemblyPath, string strDataBase,string strTableName, string strEntityName,string strCode)
     73         {
     74             
     75             
     76             StringBuilder sb = new StringBuilder();
     77             //加上要编译部分代码的头部和尾部
     78             //头部
     79             sb.Append("using System;");
     80             sb.Append("using System.Data;");
     81             sb.Append("using System.Text;");
     82             sb.Append("using System.Linq;");
     83             sb.Append("using System.Globalization;");
     84             sb.Append("using System.Collections.Generic;");
     85             sb.Append("using CodeMaker.Model;");
     86             sb.Append("using CodeMaker.BLL;");
     87             sb.Append("using CodeMaker.Engine;");
     88             sb.Append("namespace DynamicCodeGenerate");
     89             sb.Append("{");
     90 
     91             
     92 
     93             sb.Append("   public class CodeGenerate");
     94             sb.Append("   {");
     95             sb.Append("        public string OutPut()");
     96             sb.Append("        {");
     97 
     98             //读取数据实体的属性的代码段
     99             sb.Append(GetEntity(strDBType, DALAssemblyPath, strDataBase, strTableName, strEntityName));
    100 
    101             sb.Append(strCode);
    102 
    103             //返回值,字符串
    104             sb.Append("         return s.ToString(); ");
    105             sb.Append("        }");
    106             //fOutPut方法结束
    107             //首字母大写方法
    108             sb.Append("        public string ToTitleCase(string str)");
    109             sb.Append("        {");
    110             sb.Append("          return str.Substring(0,1).ToUpper()+str.Substring(1);");
    111             sb.Append("        }");
    112             //首字母小写方法
    113             sb.Append("        public string ToLowerCase(string str)");
    114             sb.Append("        {");
    115             sb.Append("          return str.Substring(0,1).ToLower()+str.Substring(1);");
    116             sb.Append("        }");
    117             
    118             sb.Append("   }");
    119             sb.Append("}");
    120 
    121             return DoCompile(sb.ToString());
    122         }
    123 
    124         private static string GetEntity(string strDBType, string DALAssemblyPath, string strDataBase, string strTableName, string strEntityName)
    125         {
    126             StringBuilder sb = new StringBuilder();
    127             sb.Append("CodeMaker.BLL.EntityBLL bll = new CodeMaker.BLL.EntityBLL("" + DALAssemblyPath + "");");
    128             sb.Append("IList<CodeMaker.Model.Entity> es = bll.GetEntityList("" + strDataBase + "", "" + strTableName + "");");
    129             sb.Append("string EntityName="" + strEntityName + "";");//实体名,供模板中的代码段使用
    130             sb.Append("string TableName="" + strTableName + "";");//表名,供模板中的代码段使用
    131             sb.Append("string DBType="" + strDBType + "";");//数据库组件,判断数据库种类SQLSERVER,MYSQL,供模板中的代码段使用
    132             sb.Append("string TablePri=(es.Where(x=>x.IsPri=="YES").Count()>0)?es.Where(x=>x.IsPri=="YES").ToList()[0].ColumnName:"";");//表的主键列 名称
    133             sb.Append("string TablePriDataType=(es.Where(x=>x.IsPri=="YES").Count()>0)?CodeAnalysis.ToDataTypeFormat(es.Where(x=>x.IsPri=="YES").ToList()[0].DataType,DBType):"";");//表的主键列 数据类型
    134             return sb.ToString();
    135            
    136         }
    137 
    138         public static string GenerateCode()
    139         {
    140             return "";
    141         }
    142     }
    143 }
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Text.RegularExpressions;
      6 
      7 namespace CodeMaker.Engine
      8 {
      9     public class CodeAnalysis
     10     {
     11         public static string Hello()
     12         {
     13             return "Hello";
     14         }
     15 
     16         public static string ToCSharpCode(string strContent)
     17         {
     18             StringBuilder sb = new StringBuilder();
     19             //需要逐行解析
     20             string[] ss = strContent.Split('
    ');
     21             string strT=string.Empty;
     22             if (ss.Length > 0)
     23             {
     24                 sb.Append("StringBuilder s = new StringBuilder();");//如果行数不为0,则需要声明字符串拼接
     25                 sb.Append(System.Environment.NewLine);
     26             }
     27             for (int i = 0; i < ss.Length; i++)
     28             {
     29                 //处理字符串行
     30                 sb.Append(DealCode(ss[i]));
     31                 sb.Append(System.Environment.NewLine);
     32               
     33 
     34             }
     35 
     36             return sb.ToString();
     37         }
     38 
     39         /// <summary>
     40         /// 单行字符串处理
     41         /// </summary>
     42         /// <param name="strLine"></param>
     43         /// <returns></returns>
     44         private static string DealCode(string strLine)
     45         {
     46             //判断当该行是无特殊代码行。特殊代码(<-$、$->)
     47 
     48             strLine = Regex.Replace(strLine, @"[
    ]", "");  //替换掉常量中的换行符
     49            
     50            
     51             if (strLine.Contains("<-$") && strLine.Contains("$->"))
     52             {
     53                 //有整行特殊代码段
     54                 //strLine = strLine.Replace(""", "\"");
     55                 strLine = strLine.Replace("<-$", "");
     56                 strLine = strLine.Replace("$->", "");
     57 
     58                 //strLine += "s.Append(System.Environment.NewLine);";
     59             }
     60             else if (strLine.Contains("<+$") && strLine.Contains("$+>"))
     61             {
     62                 //有变量取值代码段
     63                 strLine = strLine.Replace(""", "\"");
     64                 strLine = """+strLine+"\n"";//前后先加引号,后面加个换行
     65                 strLine = strLine.Replace("<+$", ""+");
     66                 strLine = strLine.Replace("$+>", "+"");
     67                
     68                 
     69                 strLine = "s.Append("+ strLine +");";
     70             }
     71             else
     72             { 
     73                 //不是特殊代码行
     74                 //strLine = "s.Append("" + strLine + ""); s.Append(System.Environment.NewLine);" ;
     75                 strLine = strLine.Replace(""", "\"");
     76                 strLine = "s.Append("" + strLine + "\n");";
     77             }
     78 
     79             return strLine;
     80         }
     81 
     82         #region 供动态编译的代码段中调用的静态方法
     83 
     84         /// <summary>
     85         /// 数据库字段数据类型 转为 java语言中的数据类型
     86         /// </summary>
     87         /// <param name="strDBColumnType">数据库字段数据类型</param>
     88         /// <param name="strDBType">数据库MYSQL  SQLSERVER</param>
     89         /// <returns></returns>
     90         public static string ToJavaDataType(string strDBColumnType, string strDBType)
     91         {
     92             string strT = string.Empty;
     93 
     94             //根据strDBType 判断数据库是什么,然后转换为程序语言中的数据类型
     95             switch (strDBType)
     96             {
     97                 case "SQLSERVER":
     98                     var stringwords = new string[]{"char","varchar","text","nchar","nvarchar","ntext"};
     99                     var intwords = new string[]{"int","smallint","tinyint"};
    100                     var boolwords = new string[] { "bit"};
    101                     var longwords = new string[] { "bigint"};
    102                     var decimalwords = new string[] { "numeric", "decimal", "money","smallmoney","float","real" };
    103                     var datewords = new string[] { "datetime", "smalldatetime" };
    104                     if (stringwords.Contains(strDBColumnType.ToLower()))
    105                     { 
    106                         strT="String";
    107                     }
    108                     else if (intwords.Contains(strDBColumnType.ToLower()))
    109                     {
    110                         strT = "int";
    111                     }
    112                     else if (longwords.Contains(strDBColumnType.ToLower()))
    113                     {
    114                         strT = "long";
    115                     }
    116                     else if (boolwords.Contains(strDBColumnType.ToLower()))
    117                     {
    118                         strT = "boolean";
    119                     }
    120                     else if (decimalwords.Contains(strDBColumnType.ToLower()))
    121                     {
    122                         strT = "decimal";
    123                     }
    124                     else if (datewords.Contains(strDBColumnType.ToLower()))
    125                     {
    126                         strT = "DateTime";
    127                     }
    128                     else
    129                     {
    130                         strT = "String";
    131                     }
    132 
    133 
    134                     break;
    135 
    136                 case "MYSQL":
    137                      var stringwords1 = new string[]{"char","varchar","text","tinytext","mediumtext","longtext"};
    138                     var intwords1 = new string[]{"smallint","tinyint","mediumint"};
    139                     var boolwords1 = new string[] { "bit"};
    140                     var longwords1 = new string[] { "int,bigint", "integer" };
    141                     var decimalwords1 = new string[] { "float", "decimal", "double" };
    142                     var datewords1 = new string[] { "datetime", "date" };
    143                     if (stringwords1.Contains(strDBColumnType.ToLower()))
    144                     {
    145                         strT = "String";
    146                     }
    147                     else if (intwords1.Contains(strDBColumnType.ToLower()))
    148                     {
    149                         strT = "int";
    150                     }
    151                     else if (longwords1.Contains(strDBColumnType.ToLower()))
    152                     {
    153                         strT = "long";
    154                     }
    155                     else if (boolwords1.Contains(strDBColumnType.ToLower()))
    156                     {
    157                         strT = "boolean";
    158                     }
    159                     else if (decimalwords1.Contains(strDBColumnType.ToLower()))
    160                     {
    161                         strT = "decimal";
    162                     }
    163                     else if (datewords1.Contains(strDBColumnType.ToLower()))
    164                     {
    165                         strT = "DateTime";
    166                     }
    167                     else
    168                     {
    169                         strT = "String";
    170                     }
    171 
    172 
    173                     break;
    174 
    175                 default:
    176                     break;
    177             }
    178 
    179             return strT;
    180         }
    181 
    182         /// <summary>
    183         /// 数据库字段数据类型 转为 c# 语言中的数据类型
    184         /// </summary>
    185         /// <param name="strDBColumnType">数据库字段数据类型</param>
    186         /// <param name="strDBType">数据库MYSQL  SQLSERVER</param>
    187         /// <returns></returns>
    188         public static string ToCSDataType(string strDBColumnType, string strDBType)
    189         {
    190             string strT = string.Empty;
    191 
    192             //根据strDBType 判断数据库是什么,然后转换为程序语言中的数据类型
    193             switch (strDBType)
    194             {
    195                 case "SQLSERVER":
    196                     var stringwords = new string[]{"char","varchar","text","nchar","nvarchar","ntext"};
    197                     var intwords = new string[]{"int","smallint","tinyint"};
    198                     var boolwords = new string[] { "bit"};
    199                     var longwords = new string[] { "bigint"};
    200                     var decimalwords = new string[] { "numeric", "decimal", "money","smallmoney","float","real" };
    201                     var datewords = new string[] { "datetime", "smalldatetime" };
    202                     if (stringwords.Contains(strDBColumnType.ToLower()))
    203                     { 
    204                         strT="string";
    205                     }
    206                     else if (intwords.Contains(strDBColumnType.ToLower()))
    207                     {
    208                         strT = "int";
    209                     }
    210                     else if (longwords.Contains(strDBColumnType.ToLower()))
    211                     {
    212                         strT = "long";
    213                     }
    214                     else if (boolwords.Contains(strDBColumnType.ToLower()))
    215                     {
    216                         strT = "bool";
    217                     }
    218                     else if (decimalwords.Contains(strDBColumnType.ToLower()))
    219                     {
    220                         strT = "decimal";
    221                     }
    222                     else if (datewords.Contains(strDBColumnType.ToLower()))
    223                     {
    224                         strT = "DateTime";
    225                     }
    226                     else
    227                     {
    228                         strT = "string";
    229                     }
    230 
    231 
    232                     break;
    233 
    234                 case "MYSQL":
    235                      var stringwords1 = new string[]{"char","varchar","text","tinytext","mediumtext","longtext"};
    236                     var intwords1 = new string[]{"smallint","tinyint","mediumint"};
    237                     var boolwords1 = new string[] { "bit"};
    238                     var longwords1 = new string[] { "int,bigint", "integer" };
    239                     var decimalwords1 = new string[] { "float", "decimal", "double" };
    240                     var datewords1 = new string[] { "datetime", "date" };
    241                     if (stringwords1.Contains(strDBColumnType.ToLower()))
    242                     { 
    243                         strT="string";
    244                     }
    245                     else if (intwords1.Contains(strDBColumnType.ToLower()))
    246                     {
    247                         strT = "int";
    248                     }
    249                     else if (longwords1.Contains(strDBColumnType.ToLower()))
    250                     {
    251                         strT = "long";
    252                     }
    253                     else if (boolwords1.Contains(strDBColumnType.ToLower()))
    254                     {
    255                         strT = "bool";
    256                     }
    257                     else if (decimalwords1.Contains(strDBColumnType.ToLower()))
    258                     {
    259                         strT = "decimal";
    260                     }
    261                     else if (datewords1.Contains(strDBColumnType.ToLower()))
    262                     {
    263                         strT = "DateTime";
    264                     }
    265                     else
    266                     {
    267                         strT = "string";
    268                     }
    269 
    270 
    271                     break;
    272 
    273                 default:
    274                     break;
    275             }
    276 
    277             return strT;
    278         }
    279 
    280         /// <summary>
    281         /// 把小写的sqlserver数据库中的数据类型转为sqlserver参数格式,例如 SqlDbType.VarChar
    282         /// </summary>
    283         /// <param name="strDataType"></param>
    284         /// <param name="strDBType">数据库MYSQL  SQLSERVER</param>
    285         /// <returns></returns>
    286         public static string ToDataTypeFormat(string strDataType,string strDBType)
    287         {
    288             string strT = string.Empty;
    289             switch (strDataType.ToLower())
    290             {
    291                 case "int":
    292                     strT = "Int";
    293                     break;
    294                 case "varchar":
    295                     strT = "VarChar";
    296                     break;
    297                 case "char":
    298                     strT = "Char";
    299                     break;
    300                 case "bigint":
    301                     strT = "BigInt";
    302                     break;
    303                 case "nvarchar":
    304                     strT = "NVarChar";
    305                     break;
    306                 case "datetime":
    307                     strT = "DateTime";
    308                     break;
    309                 case "smalldatetime":
    310                     strT = "SmallDateTime";
    311                     break;
    312                 case "bit":
    313                     strT = "Bit";
    314                     break;
    315                 case "text":
    316                     strT = "Text";
    317 
    318                     break;
    319                     case "decimal":
    320                     strT = "Decimal";
    321                     break;
    322                     case "ntext":
    323                     strT = "NText";
    324                     break;
    325                 default:
    326                     strT = "VarChar";
    327                     break;
    328             }
    329 
    330             return strT;
    331         }
    332 
    333         /// <summary>
    334         /// 获取数据类型或控件的简写,用于前缀命名
    335         /// </summary>
    336         /// <param name="strLongName"></param>
    337         /// <returns></returns>
    338         public static string ToNameFormat(string strLongName)
    339         {
    340             string strT = string.Empty;
    341             switch (strLongName.ToLower())
    342             {
    343                 case "int":
    344                     strT = "int";
    345                     break;
    346                 case "string":
    347                     strT = "str";
    348                     break;
    349                 case "char":
    350                     strT = "ch";
    351                     break;
    352                 case "long":
    353                     strT = "long";
    354                     break;
    355                 case "float":
    356                     strT = "float";
    357                     break;
    358                 case "datetime":
    359                     strT = "date";
    360                     break;
    361                 case "double":
    362                     strT = "double";
    363                     break;
    364                 case "bool":
    365                     strT = "Is";
    366                     break;
    367                 case "decimal":
    368                     strT = "dec";
    369                     break;
    370                 case "boolean":
    371                     strT = "Is";
    372                     break;
    373                 default:
    374                     strT = "x";
    375                     break;
    376             }
    377 
    378             return strT;
    379         }
    380         #endregion
    381     }
    382 }

     --------------------------------------------------------------------------

    有位博友提到过T4模板,我也看了一点点,但是我考虑的是不单单生成c#代码,目标代码还要java,因为目前正在转java方向。为了灵活性,我觉得自己定义规则比较放心,也许这个想法不成熟,但是先试试吧

    下载链接

    http://www.cnblogs.com/allanyang/p/4702467.html

  • 相关阅读:
    Exchange 2013与 Office Web Apps 整合
    SharePoint2013 以其他用户登录和修改AD域用户密码 功能
    sharepoint 2010 自定义页面布局
    sharepoint 2010 记录管理 对象模型
    SharePoint2010 对象模型 关联列表
    在SharePoint Server 2010中更改“我的网站”
    xenapp 6.5 客户端插件第一次安装总是跳到官网
    如何解决在Windows Server 2008 R2 上安装证书服务重启后出现 CertificationAuthority 91错误事件
    在Win7 Hyper-v虚拟机中挂接真实机的声卡
    win8 中如何删除 共享文件夹 用户名和密码
  • 原文地址:https://www.cnblogs.com/allanyang/p/4687534.html
Copyright © 2011-2022 走看看