c#使用dotliquid创建自定义代码模板
在编写asp.net webapi 项目时,对于常规的curd操作,在实体建立后,ctrl、service等代码基本上都有大致相同的结构,借助dotliquid自行编写代码模板,可减少一些重复的工作
以生成ctrl为例:
引入依赖-DotLiquid
dotnet add package DotLiquid --version 2.3.197
创建替换模板类
CodeGenerator/Models/CtrlTemplateModel.cs
主要用来携带用来替换模板的信息
using DotLiquid;
namespace CodeGenerator.Models;
public class CtrlTemplateModel : ILiquidizable
{
// 1.项目名
public string ProjectName { get; set; }
// 2.业务名
public string BussName { get; set; }
// 3. 实体名
public string EntityName { get; set; }
// 业务路径
public string Namespace
{
get => ProjectName +"."+ BussName;
}
// 实体变量名-实体名小写 -由实体名获取
public string EntityLowerName
{
get => FirstCharToLower(EntityName);
}
public static string FirstCharToLower(string input)
{
if (string.IsNullOrEmpty(input))
{
return input;
}
return input.Substring(0, 1).ToLower() + input.Substring(1);
}
public object ToLiquid()
{
return new
{
ProjectName,
BussName,
Namespace,
EntityName,
EntityLowerName
};
}
}
创建用于替换的信息
此json文件用来反序列成Models的c#对象,用来创建携带替换模板信息的实例对象,实际上简单点直接new CtrlTemplateModel 也是可以的
CodeGenerator/JsonTemp/ctrl.json
{
"ProjectName": "WebApi",
"BussName": "basebuss",
"EntityName": "User"
}
创建模板
CodeGenerator/Templates/CtrlTemplate
简单使用 {{ Model.属性 }} ,详细语法请自行查找,基本上需要了解基础替换、循环替换、条件替换和空格处理就可以解决多数问题了。
using AutoMapper;
using CommonHelp.util;
using Microsoft.AspNetCore.Mvc;
using {{ Model.ProjectName }}.basebuss.dto;
using {{ Model.Namespace }}.service;
using {{ Model.ProjectName }}.filters;
using {{ Model.ProjectName }}.migration.models;
using {{ Model.ProjectName }}.page;
namespace {{ Model.Namespace }}.controllers ;
[Transactional]
[ApiController]
[Route("api/[controller]")]
public class {{ Model.EntityName }}Controller(
ILogger<{{ Model.EntityName }}Controller> logger,
IMapper mapper,
I{{ Model.EntityName }}Service service
)
: ControllerBase
{
// 请求示例 http://localhost:5026/api/{{ Model.EntityName }}?PageSize=10&PageNum=1&SortField=price,desc;imageUrl,asc&Filter=id:eq:386c60e8373c4c3e99b7aeabfa9b3a86;productId:eq:9988
/// <summary>
/// 查找-过滤、分页
/// </summary>
[HttpGet]
public OkObjectResult Get{{ Model.EntityName }}List(
[FromQuery] {{ Model.EntityName }}Dto? {{ Model.EntityLowerName }}Dto
)
{
if (null != {{ Model.EntityLowerName }}Dto.PageSize && null != {{ Model.EntityLowerName }}Dto.PageNum)
{
logger.LogInformation("分页查询dto:{}", ObjectUtil.ToString({{ Model.EntityLowerName }}Dto));
List<{{ Model.EntityName }}> pageList =
service.Get{{ Model.EntityName }}List({{ Model.EntityLowerName }}Dto, {{ Model.EntityLowerName }}Dto.PageSize, {{ Model.EntityLowerName }}Dto.PageNum);
int totalCount = service.TotalCount({{ Model.EntityLowerName }}Dto);
List<{{ Model.EntityName }}Dto> restList = new List<{{ Model.EntityName }}Dto>();
mapper.Map(pageList, restList);
PagedResult<{{ Model.EntityName }}Dto> result = new PagedResult<{{ Model.EntityName }}Dto>(restList, totalCount);
return Ok(result);
}
else
{
logger.LogInformation("条件查找:{}", ObjectUtil.ToString({{ Model.EntityLowerName }}Dto));
List<{{ Model.EntityName }}> dataList = comService.GetCommodities({{ Model.EntityLowerName }}Dto);
List<{{ Model.EntityName }}Dto> restList = new List<{{ Model.EntityName }}Dto>();
mapper.Map(dataList, restList);
return Ok(restList);
}
}
/// <summary>
/// id查找
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}")]
public OkObjectResult Get{{ Model.EntityName }}(String id)
{
logger.LogInformation("id查找:{}", id);
IQueryable<{{ Model.EntityName }}> dataList = comService.Get{{ Model.EntityName }}(id);
List<{{ Model.EntityName }}Dto> restList = new List<{{ Model.EntityName }}Dto>();
mapper.Map(dataList, restList);
return Ok(restList);
}
/// <summary>
/// 新增
/// </summary>
/// <param name="{{ Model.EntityLowerName }}Dto"></param>
/// <returns></returns>
[HttpPost]
public ActionResult<{{ Model.EntityName }}Dto> Post{{ Model.EntityName }}({{ Model.EntityName }}Dto {{ Model.EntityLowerName }}Dto)
{
logger.LogInformation("one新增:{}", {{ Model.EntityLowerName }}Dto.ToString());
if (!ModelState.IsValid)
{
logger.LogInformation("校验不通过");
return BadRequest(ModelState);
}
string uid = Guid.NewGuid().ToString().Replace("-", "");
//重置 id
{{ Model.EntityLowerName }}Dto.Id = uid;
{{ Model.EntityName }} {{ Model.EntityLowerName }} = new {{ Model.EntityName }}();
mapper.Map({{ Model.EntityLowerName }}Dto, {{ Model.EntityLowerName }});
Boolean result = comService.Add{{ Model.EntityName }}({{ Model.EntityLowerName }});
return result ? Ok(uid) : BadRequest("新增未成功!");
}
/// <summary>
/// 删除-id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public IActionResult Delete{{ Model.EntityName }}(String id)
{
logger.LogInformation("one删除id:{}", id);
Int32 result = comService.Delete{{ Model.EntityName }}ById(id);
if (result > 0)
{
//if (true) throw new Exception();
return Ok(result);
}
return BadRequest("删除不成功!");
}
/// <summary>
/// 更新-id 实体
/// </summary>
/// <param name="id"></param>
/// <param name="{{ Model.EntityLowerName }}Dto"></param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task<IActionResult> Put{{ Model.EntityName }}({{ Model.EntityName }}Dto {{ Model.EntityLowerName }}Dto)
{
logger.LogInformation("edit实体-忽略null属性:{}", ObjectUtil.ToString({{ Model.EntityLowerName }}Dto));
{{ Model.EntityName }} {{ Model.EntityLowerName }} = new {{ Model.EntityName }}();
mapper.Map({{ Model.EntityLowerName }}Dto, {{ Model.EntityLowerName }});
int task = await comService.Update{{ Model.EntityName }}Async({{ Model.EntityLowerName }});
if (task > 0)
{
return Ok(task);
}
return Ok("数据未更新:" + task);
}
/// <summary>
/// 部分更新
/// </summary>
/// <param name="{{ Model.EntityLowerName }}Dto"></param>
/// <returns></returns>
[HttpPatch("{id}")]
public async Task<IActionResult> Patc{{ Model.EntityName }}({{ Model.EntityName }}Dto {{ Model.EntityLowerName }}Dto)
{
logger.LogInformation("edit实体-:{}", ObjectUtil.ToString({{ Model.EntityLowerName }}Dto));
{{ Model.EntityName }} {{ Model.EntityLowerName }} = new {{ Model.EntityName }}();
mapper.Map({{ Model.EntityLowerName }}Dto, {{ Model.EntityLowerName }});
int task = await comService.Update{{ Model.EntityName }}Async({{ Model.EntityLowerName }});
if (task > 0)
{
return Ok(task);
}
return Ok("数据未更新:" + task);
}
}
执行代码
net.9 使用顶级语句 在Program.cs中
// 工作主目录
string workPath = "D:/Datas/WebApi/CodeGenerator/";
//输出主目录
string outPath = "D:/Datas/WebApi/CodeGenerator/";
// 模板文件夹
string templatePath = workPath + "Templates/";
//类模板文件
string templatefilename = "ClassTemplate";
//类模板路径
string templatefile = templatePath + templatefilename;
await createCtrl(workPath, outPath);
async Task createCtrl(string workPath, string outPath)
{
var model = JsonSerializer.Deserialize<CtrlTemplateModel>(File.ReadAllText(workPath + "JsonTemp/ctrl.json"));
// 读取模板内容,字符串类型
var template = Template.Parse(File.ReadAllText(templatePath + "CtrlTemplate"));
// 核心执行方法
var result = template.Render(Hash.FromAnonymousObject(new { model = model }));
Console.WriteLine(result);
}

浙公网安备 33010602011771号