zoukankan      html  css  js  c++  java
  • RazorEngine.NetCore 相见恨晚,它让我彻底放弃了T4模板

       在dbfrist 时代,用T4模板生成代码,貌似还没有感觉到别扭。但是到了codefrist 后,我想要实体生成生成备注,我就得想方设法的去把备注弄到数据库,然后 还要处理模型中类型像枚举这种属性,渐渐的感觉到了吃力。要不换种方式吧,想着去反射实体,但是用T4去处理这种反射,还是感觉到有点吃力,就觉得能不能直接像我们直接写后台程序一样去解析,后面想到了Razor 引擎,经过进一步的了解,发现大神封装了一个组件 RazorEngine.NetCore,他很好的解决了我的问题。
       下面就让我们来了解下这个组件吧,先让我们得到这个组件如图

      有了组件,我们先去编写对应自己业务的模板先吧,就比如我这个我创建一个AddDto,我创建的模板如下:

    @*@model LazyBoy.Dtos.DbTableDto*@
    @using LazyBoy.Dtos;
    @using LazyBoy.Extensions;
    @using LazyBoy.Enums;
    
    using System;
    using AutoMapper;
    using Domain.Models.Enum;
    using Domain.Models.Entitys;
    using Sy.ExpressionBuilder.Modules;
    using System.ComponentModel.DataAnnotations;
    using Sy.ExpressionBuilder.Modules;
    using Domain.Models.Entitys;
    using AutoMapper;
    using Domain.Models.Enum;
    
    
    namespace @GeneratorConfig.DtoNameSpaceName
    {
        /// <summary>
        /// @Model.Remark
        ///</summary>
        [AutoMap(typeof(@(@StringExtension.FirstToUp(@Model.TableName))), ReverseMap = true)]
        public partial class  BaseAdd@(@StringExtension.FirstToUp(@Model.TableName))Dto
        {
        @foreach (var pm in @Model.DbColumns)
        {
        @if ((pm.ColumnName.ToLower() != "id"&&(pm.PropertyType == EnumPropertyType.Field || pm.PropertyType == EnumPropertyType.Enum) ))
        {
    
            @:/// <summary>
            @:/// @pm.Remark
            @:/// </summary>
            @:[Display(Name ="@(pm.Remark)")]
            @if (pm.IsRequired)
            {
            @:[Required(ErrorMessage ="@(pm.Remark)不能为空")]
            }
            @if (pm.StringLengthMax!=0)
            {
            @:[StringLength(@(pm.StringLengthMax), MinimumLength =@(pm.StringLengthMin), ErrorMessage = "@(pm.Remark)的长度为{2}至{1}个字符")]
            }
            else if (pm.StringLengthMin!=0)
            {
            @:[StringLength(@(pm.StringLengthMin), ErrorMessage = "@(pm.Remark)的长度至少为{1}个字符")]
            }
            @if(pm.RangeMax!=null)
            {
            @:[Range(@(pm.RangeMax), MinimumLength =@(pm.RangeMin), ErrorMessage="@(pm.Remark)的范围在{1}至{2}之间")]
            }
            @if(pm.Regular!=null)
            {
            @:[RegularExpression("@(pm.Regular)", ErrorMessage = "@(pm.Remark)@(pm.ErrorMessage)")]
            }
            @:public virtual @pm.ColumnType @(pm.IsNullable==true?"?":"")  @StringExtension.FirstToUp(pm.ColumnName) { get;set;}
    
        }
        }
        }
    }

     温馨提示,代码头部这个引用后台返回的实体的这个,我们编写的时候放出来,这样我们就可以像写Razor 视图一样了,后面生成代码的注释掉。

     有了模板后,我们就可以生成我们要的AddDto了,在起始项(.net6 直接在Program) 添加并且编译我们的模板,如下:
     

                //打开并且读取模板
                string template = File.ReadAllText(filePath); //CreateDto.cshtml
                var nameKey = templateName.ToLower().Replace(".cshtml", "");
                //添加模板
                Engine.Razor.AddTemplate(nameKey, template);
                //编译模板
                Engine.Razor.Compile(nameKey, null);

     然后我们根据反射拿到实体类库的解析类,传给引擎就好了
     

     var result = Engine.Razor.Run(templateName.ToLower(), null, item);
    templateName.ToLower(),对应我们添加模板的key,item对应单个实体的解析类,下面给出我的示例代码:
     /// <summary>
            /// 创建所有类型Dto
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            public IResultModel CreateAllBaseDto()
            {
                CreateDtoManager dtoManager = new CreateDtoManager();
                var dbTables = dtoManager.GetDbTable();
                var dtoPath = _configuration.GetSection("DbConfigInfo")["CodeResourcePath"];
                var templateNames = _configuration.GetSection("DbConfigInfo")["BaseDtoTemplateName"];
                foreach (var item in dbTables)
                {
                    foreach (var templateName in templateNames?.Split(',').ToList())
                    {
                        var result = Engine.Razor.Run(templateName.ToLower(), null, item);
                        var filePath = $"{dtoPath}/BaseDtos/{item.SchemaName.GetPath('_')}/{item.TableName}s";
                        var prefix = "";
                        if (templateName.Contains("add", StringComparison.OrdinalIgnoreCase))
                            prefix = "Add";
                        if (templateName.Contains("all", StringComparison.OrdinalIgnoreCase))
                            prefix = "All";
                        if (templateName.Contains("edit", StringComparison.OrdinalIgnoreCase))
                            prefix = "Edit";
                        string fileName = filePath + "\\" + $"{prefix}Base{item.TableName}Dto.cs";
    
                        //保存文件
                        FileHelper.Save(fileName, result);
                    }
                }
                return ResultTo.Success("生成成功");
            }

    让我们看看效果

     然后保存在本地就大功告成了,我集中放到了一个文件夹,这样方便直接拷贝替换(集成到项目可以直接替换,但是有覆盖风险,没敢),后面看看最后的成果。



  • 相关阅读:
    Windows Azure Cloud Service (14) 使用Windows Azure诊断收集日志记录数据
    Windows Azure Cloud Service (13) 用Visual Studio 2010 将应用程序部署到Windows Azure平台
    Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
    Windows Azure Storage (5) Windows Azure Drive
    Windows Azure Storage (7) 使用工具管理Windows Azure Storage
    SQL Azure(二) SQL Azure vs SQL Server
    webbrowser的自动提交
    提取视频的背景声音的软件
    Listview列排序的bug原因
    两个奇怪的问题
  • 原文地址:https://www.cnblogs.com/noert/p/15769857.html
Copyright © 2011-2022 走看看