C#实现代码生成器
最近在用layui做后台管理,增删改查这些一成不变的东西写起来浪费大量时间,于是做了个简单的代码生成器快速生成
代码生成器的原理其实很简单,都是基于模板实现替换,Razor是个不错的选择(或者Nvelocity。。),还可以用字符串占位符替换的方式生成。
1. 技术栈
0.Asp.net
1.模板引擎RazorEngine
2.ORM使用SqlSugar
3.生成压缩包SharpZipLib
2.源码下载
https://gitee.com/huzhihao/code_generator.git
3.代码分析
核心代码就两个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>
/// 数据库名
/// </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", "应用类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>
/// 类型转化
/// </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); } /**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
* 例如:HELLO_WORLD->HelloWorld
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
/// <summary>
/// 转换为驼峰命名
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static string ToCamelName(string name)
{
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || string.IsNullOrEmpty(name))
{
// 没必要转换
return "";
}
else if (!name.Contains("_"))
{
// 不含下划线,仅将首字母大写
return name.Substring(0, 1).ToUpper() + name.Substring(1).ToLower();
}
// 用下划线将原始字符串分割
string[] camels = name.Split('_');
foreach (string camel in camels)
{
// 跳过原始字符串中开头、结尾的下换线或双重下划线
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();
}
}
}
C#实现代码生成器的更多相关文章
- springmvc SSM shiro redis 后台框架 多数据源 代码生成器
A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单 下载地址 ; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类 ...
- 分享一个与ABP配套使用的代码生成器源码
点这里进入ABP系列文章总目录 分享一个与ABP配套使用的代码生成器源码 真对不起关注我博客的朋友, 因最近工作很忙, 很久没有更新博客了.以前答应把自用的代码生成器源码共享出来, 也一直没有时间整理 ...
- ABP配套代码生成器(ABP Code Generator)帮助文档,实现快速开发
ABP代码生成器介绍 针对abp这个框架做了一个代码生成器,功能强大.分为两大功能点,一个是数据层,一个是视图层. 数据服务层:通过它,可以实现表设计.领域层初始化.多语言.automapper自动注 ...
- 基于AgileEAS.NET SOA 中间件领域模型数据器快速打造自己的代码生成器
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- Razor Engine,实现代码生成器的又一件利器
Razor Engine,之前仅仅是ASP.NET MVC的一种View引擎,目前已经完全成为一种可以独立使用的模版引擎,并且已经成为了CodePlex上一个开源的项目(http://razoreng ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 更优美的Oracle数据库上的代码生成器
代码生成器进行了改进,针对Oracle数据库生成更优美的代码.这样生成出来的代码,更像微软的风格,更像C#.NET的标准规范,阅读起来也更优美.把Oracle表字段名默认大写, 有_分割等进行了优化, ...
- [NHibernate]代码生成器的使用
目录 写在前面 文档与系列文章 代码生成器的使用 总结 写在前面 前面的文章介绍了nhibernate的相关知识,都是自己手敲的代码,有时候显得特别的麻烦,比如你必须编写持久化类,映射文件等等,举得例 ...
- RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-29(提供下载)
本次主要更新内容: 1.增加对Oracle表创建语句的查看. 2.新增对MySql的代码生成支持. 3.全面重构对多线程的支持,改变以前会无故退出的现象. RDIFramework.NET代码生成器V ...
- RDIFramework.NET平台代码生成器V3.0版本全新发布-更新于20160518(提供下载)
最新版本请转到:RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-08(提供下载) RDIFramework.NET代码生成器V3.0版本修改了针对3.0版本的 ...
- XML代码生成器——XMLFACTORY 简介(四)
XML代码生成器——XMLFACTORY 简介(四) 这一篇我们讲“类属性”页签的配置功能,您将了解到:如何为元素子值指定类属性的名称,数据类型,及容器类型. 如果,你没看过这个系列的第一篇文章,请先 ...
随机推荐
- python — 协程
1. 协程 1.1 协程基础 1.协程 :能够在一个线程下的多个任务之间来回切换,那么每一个任务都是一个协程. 2.协程的优点: 1.一个线程中的阻塞都被其他的各种任务沾满了 2.让操作系统觉得这个线 ...
- 第10章:深入浅出Ansible
1.Ansible介绍 1).Ansible的优点 Ansible是一个简单的自动化引擎,可完成配置管理.引用部署.服务编排以及其他各种IT需求 Ansible是Python开发并实现的开源软件,其依 ...
- 【KMP】OKR-Periods of Words
[KMP]OKR-Periods of Words 题目描述 串是有限个小写字符的序列,特别的,一个空序列也可以是一个串.一个串P是串A的前缀,当且仅当存在串B,使得A=PB.如果P≠A并且P不是一个 ...
- 使用Golang时遇到的一些坑
1. [致命]不是所有Panic都能捕获 我们知道Golang给开发人员提供recover()机制,对堆栈异常(panic)进行捕获并自定义其处理逻辑.下面举个例子: 构造一个除0的异常场景: 输出结 ...
- Python 面向对象编程详解
Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...
- zepto学习(一)之click事件和tap事件比较
一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap分别 ...
- 5. Java的注释,标识符、标识符的命名规范
什么是标识符符? 凡是可以由自己命名的地方都称为修饰符. 例: 项目名 ,包名 ,类名 .方法名 2. 命名规范. ① 不可使用java关键字和保留字,但是可以包含关键字和保留字. ② ...
- 【PR笔记】一、打造希区柯克变焦效果
1. 导入素材,“链接选择项”关闭,删除音频 2. 添加效果--视频效果--扭曲--视频稳定器, 然后程序帮我们自动稳定 3.视频首尾添加关键帧,首帧缩放200% 尾帧不变, 使视频前后的主体大小差 ...
- for循环中的闭包
// 问题1:判断下面一段代码运行的结果是什么? var data = [] for (var i = 0; i < 3; i++) { data[i] = function() { conso ...
- python3使用pytesseract进行验证码识别
pytesseract介绍 1.Python-tesseract是一个基于google's Tesseract-OCR的独立封装包: 2.Python-tesseract功能是识别图片文件中文字,并作 ...