手把手撸套框架-自己写个代码生成器

目录

 

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个月的时间,能把  目录 里所有的条码填完。

 

posted @ 2020-07-17 22:04  Near_wen  阅读(2918)  评论(1编辑  收藏  举报