C#实现代码生成器
最近在用layui做后臺管理,增刪改查這些一成不變的東西寫起來浪費大量時間,于是做了個簡單的代碼生成器快速生成
代碼生成器的原理其實很簡單,都是基于模板實現(xiàn)替換,Razor是個不錯的選擇(或者Nvelocity。。),還可以用字符串占位符替換的方式生成。
技術(shù)棧采用:
1.模板引擎RazorEngine
2.ORM使用SqlSugar
3.生成壓縮包SharpZipLib
代碼結(jié)構(gòu)如下圖:
<img class="alignnone size-full wp-image-190" src="http://www.huzhihao.cn/wp-content/uploads/2018/09/QQ截圖20180913171049-1.jpg" alt="" width="257" height="295" />
標(biāo)準(zhǔn)的Razor語法寫起來比較舒服
<img class="alignnone size-medium wp-image-196" src="http://www.huzhihao.cn/wp-content/uploads/2018/09/QQ截圖20180913173724-300x218.jpg" alt="" width="300" height="218" />
核心代碼就兩個cs:
Coder.cs
------------------------------------------
using MySqlSugar;
using RazorEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace ConsoleApp1
{
public class Coder
{
private SqlSugarClient _sqlsugarClient;
public SqlSugarClient db
{
get
{
if (_sqlsugarClient == null)
{
var conn = "Database=easycms;Data Source=127.0.0.1;User Id=root;Password=root;pooling=false;CharSet=utf8;port=3306;SslMode=None";
var db = new SqlSugarClient(conn);
_sqlsugarClient = db;
}
return _sqlsugarClient;
}
}
public string entity_template { get; set; }
public string dto_template { get; set; }
public string app_template { get; set; }
public string ctrl_template { get; set; }
/// <summary>
/// 數(shù)據(jù)庫名
/// </summary>
public string dbschema { get; set; }
public Coder()
{
var path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "實體類razor.txt");
entity_template = File.ReadAllText(path);
var dto_path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "DTO類Razor.txt");
dto_template = File.ReadAllText(dto_path);
var app_path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "應(yīng)用類razor.txt");
app_template = File.ReadAllText(app_path);
var ctrl_path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "控制器razor.txt");
ctrl_template = File.ReadAllText(ctrl_path);
dbschema = "easycms";
}
public string Builder()
{
var keyword = "sys_user,sys_dict,sys_parameter,sys_role";
var dir = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate");
if (Directory.Exists(dir))
{
Directory.Delete(dir, true);
}
StringBuilder builder = new StringBuilder();
var tables = db.SqlQuery<TableInfo>(string.Format(@"select table_name,table_comment from information_schema.tables
where table_schema='{0}'", dbschema)).ToList();
foreach (var tb in keyword.Split(','))
{
var tablecomment = tables.Find(c => c.table_name == tb).table_comment;
var ret = RazorParse(tb, tablecomment);
builder.Append(ret);
}
var srcdir = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate", "Code");
var folders = new List<string>();
folders.Add(srcdir);
var bl = new ZipHelper().ZipManyFilesOrDictorys(folders.AsEnumerable(),
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate", "Code.zip"), "");
return builder.ToString(); ;
}
public string RazorParse(string tablename, string tablecomment)
{
StringBuilder builder = new StringBuilder();
var columsInfo = db.SqlQuery<ColumnInfo>(string.Format(@"select table_name,column_name,ordinal_position,is_nullable,data_type,character_maximum_length,column_key,column_comment
from information_schema.COLUMNS
where table_schema = '{0}' and table_name = '{1}'", dbschema, tablename)).ToList();
foreach (var item in columsInfo)
{
item.data_type = Utils.GetCsType(item.data_type);
if (!item.data_type.Equals("string") && item.is_nullable.Equals("YES"))
{
item.data_type = item.data_type + "?";
}
}
#region entity
var entity_result = Razor.Parse(entity_template, new
{
EntityNameSpace = "Ace.Entity.CMS",
EntityName = tablename,
Columns = columsInfo
},"entity");
Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Entity", $"{tablename}.cs")
, entity_result);
builder.Append(entity_result);
#endregion
#region dto
var dto_result = Razor.Parse(dto_template, new
{
DtoNameSpace = "Ace.Application.CMS.Models",
DtoName = Utils.ToCamelName(tablename) + "Info",
Columns = columsInfo
},"dto");
Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Dto", $"{Utils.ToCamelName(tablename) + "Info"}.cs")
, dto_result);
builder.Append(dto_result);
#endregion
#region app
var app_result = Razor.Parse(app_template, new
{
AppNameSpace = "Ace.Application.CMS.Implements",
DtoName = Utils.ToCamelName(tablename) + "Info",
AppClassName = Utils.ToCamelName(tablename),
Table = tablename,
Columns = columsInfo
},"app");
Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Application", $"{Utils.ToCamelName(tablename) + "Service"}.cs")
, app_result);
builder.Append(app_result);
#endregion
#region controller
var ctrl_result = Razor.Parse(ctrl_template, new
{
AppClassName = Utils.ToCamelName(tablename),
DtoName = Utils.ToCamelName(tablename) + "Info",
TableComment = tablecomment,
},"ctrl");
Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Controller", $"{Utils.ToCamelName(tablename) + "Controller"}.cs")
, ctrl_result);
builder.Append(ctrl_result);
#endregion
return builder.ToString();
}
public class ColumnInfo
{
public string table_name { get; set; }
public string column_name { get; set; }
public int? ordinal_position { get; set; }
public string is_nullable { get; set; }
public string data_type { get; set; }
public int? character_maximum_length { get; set; }
public string column_key { get; set; }
public string column_comment { get; set; }
}
public class TableInfo
{
public string table_name { get; set; }
public string table_comment { get; set; }
}
}
}
-----------------------------------
Util.cs
-----------------------------------
using System.IO;
using System.Text;
namespace ConsoleApp1
{
public class Utils
{
/// <summary>
/// 類型轉(zhuǎn)化
/// </summary>
/// <param name="dbType"></param>
/// <returns></returns>
public static string GetCsType(string dbType)
{
string csType = "";
switch (dbType.ToLower())
{
case "varchar":
case "varchar2":
case "nvarchar":
case "nvarchar2":
case "char":
case "nchar":
case "text":
case "longtext":
case "string":
csType = "string";
break;
case "date":
case "datetime":
case "smalldatetime":
case "timestamp":
csType = "DateTime";
break;
case "int":
case "number":
case "smallint":
case "integer":
csType = "int";
break;
case "bigint":
csType = "Int64";
break;
case "float":
case "numeric":
case "decimal":
case "money":
case "smallmoney":
case "real":
case "double":
csType = "decimal";
break;
case "tinyint":
case "bit":
csType = "bool";
break;
case "binary":
case "varbinary":
case "image":
case "raw":
case "long":
case "long raw":
case "blob":
case "bfile":
csType = "byte[]";
break;
case "uniqueidentifier":
csType = "Guid";
break;
case "xml":
case "json":
csType = "string";
break;
default:
csType = "object";
break;
}
return csType;
}
/// <summary>
/// 保存
/// </summary>
/// <param name="path"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string Save(string path, string content)
{
string dir = path.Substring(0, path.LastIndexOf("\\") + 1);
if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
File.WriteAllText(path, content);
return path;
}
private static System.Text.RegularExpressions.Regex regSpace = new System.Text.RegularExpressions.Regex(@"\s");
/// <summary>
/// 去掉空格
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ReplaceSpace(string value)
{
if (string.IsNullOrEmpty(value))
return string.Empty;
char firstChar = value[0];
if (firstChar >= 48 && firstChar <= 57)
{
value = "_" + value;
}
return regSpace.Replace(value.Trim(), " ");
}
/// <summary>
/// 首字母大寫
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToUpperFirstword(string value)
{
if (string.IsNullOrEmpty(value))
return string.Empty;
return value.Substring(0, 1).ToUpper() + value.Substring(1);
}
/**
* 將下劃線大寫方式命名的字符串轉(zhuǎn)換為駝峰式。如果轉(zhuǎn)換前的下劃線大寫方式命名的字符串為空,則返回空字符串。</br>
* 例如:HELLO_WORLD->HelloWorld
* @param name 轉(zhuǎn)換前的下劃線大寫方式命名的字符串
* @return 轉(zhuǎn)換后的駝峰式命名的字符串
*/
/// <summary>
/// 轉(zhuǎn)換為駝峰命名
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static string ToCamelName(string name)
{
StringBuilder result = new StringBuilder();
// 快速檢查
if (name == null || string.IsNullOrEmpty(name))
{
// 沒必要轉(zhuǎn)換
return "";
}
else if (!name.Contains("_"))
{
// 不含下劃線,僅將首字母大寫
return name.Substring(0, 1).ToUpper() + name.Substring(1).ToLower();
}
// 用下劃線將原始字符串分割
string[] camels = name.Split('_');
foreach (string camel in camels)
{
// 跳過原始字符串中開頭、結(jié)尾的下?lián)Q線或雙重下劃線
if (string.IsNullOrEmpty(camel))
{
continue;
}
// 處理真正的駝峰片段
//if (result.Length == 0)
//{
// // 第一個駝峰片段,全部字母都小寫
// result.Append(camel.ToLower());
//}
//else
//{
// 其他的駝峰片段,首字母大寫
result.Append(camel.Substring(0, 1).ToUpper());
result.Append(camel.Substring(1).ToLower());
//}
}
return result.ToString();
}
}
}
<hr />
轉(zhuǎn)載于:https://www.cnblogs.com/langhaoabcd/p/10446170.html
總結(jié)
- 上一篇: laravel5.8笔记一:安装与服务器
- 下一篇: flask中的CBV , flask-s