手把手撸套框架-自己写个代码生成器
1,为什么自己写一个代码生成器?
这个上一篇文章《Sqlsugar基本搭建》中已经讲过了,因为一些代码生成器对Oracle不友好,Oracle是全大写。生成出来的model,就全部大写了。这个看着非常蛋疼,
所以萌生了自己写个代码生成器的想法。
除此之外,还有一个原因,我们知道代码生成器普遍的只生成model,当前也有些代码生成器支持自己写模板比如T4,CodeSmith等。
但是很少有代码生成器 去生成表单,因为这个就纯属定制化了,虽然也可以通过写模板搞定,但是多数情况下来说,不是自己的代码生成器,不好改动。
也有人会说,现在都不用生成前端了,有像WTM 这样的框架只要配置就好了。 还有人会说,还生成什么前端呀,现在前端都组件化了,Vue,写好组件
到处引用就行了。我只能说,大家说的都没错!各花入各眼。 但是做为一个程序员,不是应该自己尝试去拥有一个自己的代码生成器吗? 就算没有代码生成器,也应该去写一下
代码生成器的模板吧!?
话不多说,先上图:
代码生成器,是用Core 写的,之前的文章有说过core 性能非常好,但是这里我郑重提示一下:Winform 和 WPF 目前不要用core, (core 3.1)
微软现在还没来得及,把winform 和 wpf 的设计器搞好,之前更惨,之前连设计器都没有有。现在设计器也莫名其妙卡顿。
2, 说说代码生成器 引擎。
一开始代码生成器,我也想直接用T4模板,但是搜遍了百度,却没有文章把讲怎么把T4引擎 打到winform里面的,都是讲怎么在vs里面用T4,所以这里放弃了T4,
后来在朋友的推荐下,看一下Velocity,看了下也不很不错,刚准备上手,想着在几个.net 群里问一下,结果发现大家都是用Razor 引擎,我擦,我还没想到Razor,
还能干这个。。。 相比之下,Velocity还需要花时间熟悉, Razor 我熟啊。 asp.net mvc 不天天用吗···!
果断的用Razor! 这里发一下Razor 引擎的语法:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/views/razor?view=aspnetcore-3.1
就算不懂的,上手也非常快,简单看一下,就可以自己写模板了。
使用Razor 引擎,也能让我这代码生成器 的受众群体 增加一些,东西做出来嘛,就是给人用的!
3,怎么写模板。
所有的代码生成器,一个基本的原则都是 关键字替换, 但是有了引擎的加持,我们就可以 使用 编程语言,比如 for,if 这些。
我贴一个最简单 的model 实体生成 的模板代码:
using System; using System.Linq; using System.Text; using SqlSugar; namespace @ViewBag.NameSpace { /// <summary> /// @Model.Comment ///</summary> public class @Model.Name { public @(Model.Name)() { } @foreach (var item in @Model.Columns) { @:///<summary> @:///描述:@(item.Comment) @:///</summary> @:public @item.PrimativeTypeName @item.CaseCamelName { get; set; } } } }
简单的说一下,这里面的替换的内容都是哪来的,比如:
@ViewBag.NameSpace
viewBag,就不多说了,熟悉asp.net mvc 的朋友都知道,一般在控制写写ViewBig ,前端就可以获取的到,这里也一样
ViewBag ,是我在执行代码生成 之前加的:
上面看到,我在viewbag里面 还加了一个时间,不过我模板里面没有用到,一般有些人会加自己的 名字,联系方式什么的,
都可以通过viewbag 去加。
至于其他的内容则来自数据库,比如字段信息,表名,主外键,等等。。
大体来说分成两个部分,一个是表信息,一个是字段信息, 如下:
这是表信息:
public interface ITableSchema { /// <summary> /// 表名 /// </summary> string Name { get; set; } /// <summary> /// 表备注 /// </summary> string Comment { get; set; } /// <summary> /// 列名 /// </summary> List<IColumn> Columns { get; set; } /// <summary> /// 外键集合 /// </summary> List<ForeignKey> ForiegnKeys { get; set; } /// <summary> /// 唯一键集合 /// </summary> List<UniqueKey> UniqueKeys { get; set; } /// <summary> /// 主键 /// </summary> PrimaryKey PrimaryKey { get; set; } /// <summary> /// 对象类型,TABLE or VIEW /// </summary> string ObjectType { get; set; } /// <summary> /// 视图脚本 /// </summary> string ViewScript { get; set; } }
我们就可以在模板里面取这些信息,比如:
@Model.Name 表名
@Model.Comment 表备注
其他的以此类推,至于为什么是Model点出来的,因为是把整个对象扔进去了,对象在Razor里面就是Model这个变量。
字段信息,就很好理解了,就在 List<IColumn> Columns { get; set; } 里面,遍历它就可以了
using System; using System.Collections.Generic; using System.Text; namespace SugarWinner.CodeGenerator.Facade.Interfaces { /// <summary> /// 数据列接口 /// </summary> public interface IColumn { /// <summary> /// 列名 /// </summary> string Name { get; set; } /// <summary> /// 列数据长度 /// </summary> int Length { get; set; } /// <summary> /// 列精度 /// </summary> int Scale { get; set; } /// <summary> /// 数据库类型【char,number...等等】 /// </summary> string DbType { get; set; } /// <summary> /// 数据库类型转换为Csharp类型 /// </summary> Type CsharpType { get; set; } /// <summary> /// 转换为基元类型 /// </summary> string PrimativeTypeName { get; set; } /// <summary> /// 列默认值 /// </summary> string DefaultValue { get; set; } /// <summary> /// 列描述 /// </summary> string Comment { get; set; } /// <summary> /// 是否可空 /// </summary> bool IsNullable { get; set; } /// <summary> /// 是否为数字类型 /// </summary> bool IsNumeric { get; set; } /// <summary> /// 是否自动增长 /// </summary> bool IsAutoIncrement { get; set; } /// <summary> /// 列所属表 /// </summary> ITableSchema Table { get; set; } /// <summary> /// 驼峰命名 /// </summary> string CaseCamelName { get; set; } } }
前面有说,关于一些代码生成器Oracle 全大写,生成出来的字段就全大写了,所以我这里特地加了驼峰命名法,解决了Oracle 数据库的问题。
另外,要特别鸣谢Jason, 基本整个代码生成器的 实体类,以及工厂,我都是从他的代码生成器Copy出来的,实话jason的代码命名还是取的非常不错的。
说到这里,代码生成器 是一个工厂模式,不熟悉工厂模式的就建议先熟悉一下工厂,再去修改代码。
最后,目前代码生成器 只支持,Oracle,SqlServer,MySql. 虽然我上面有 Sqlite 类型,但是 我并没有去实现Sqlite。暂时没有时间去搞这个,后面有时间
后面弄吧,或者 有好心人士,帮我弄一下,可以发我邮箱我合并进去: 274733956@qq.com
最后,最后。贴一下代码连接:https://github.com/demon28/SugarWinner.CodeGenerator
整个手把手撸套框架,有了代码生成器,算是真正意义上的开始。 希望通过6个月的时间,能把 目录 里所有的条码填完。