本文介绍了一种在命令行环境下使用 Nuke 根据 XCode 模型文件生成 Entity 实体类的技术。本文假设你已经掌握了 NewLife.XCode 基本的使用方法,并且已经有了一个编写好的 XCode 模型 XML 文件。
什么是 Nuke ?
根据官方仓库的说明:Nuke 是适用于 C#/.NET 的构建系统。简单来说,我们可以使用 Nuke 实现直接使用 C# 构建 CI/CD 管道。
Nuke 快速入门
1、安装全局工具
dotnet tool install Nuke.GlobalTool --global
2、转到代码存储仓库,初始化 nuke
nuke :setup
创建过程中可能会让你选择一些信息,作为 Demo 项目,一路回车即可。
3、运行构建
nuke
Build.cs 文件
如果一切顺利,我们会在 build 目录下发现一个名为 Build.cs 的文件,核心代码如下:
class Build : NukeBuild
{
public static int Main () => Execute<Build>(x => x.Compile);
Target Clean => _ => ...... ;
Target Restore => _ => ...... ;
Target Compile => _ => ...... ;
}
其中返回值为 Target 的 Clean、Restore 和 Compile 三个方法分别代表三个构建目标。我们可以在对应的方法中编写 C# 代码来实现构建。
可以看到,程序入口默认使用了 Compile 。这表示如果我们直接执行 nuke 命令,将会默认调用 Compile 方法。
如果需要调用 Clean 方法,可以使用:
nuke Clean
或者在根目录调用 build 脚本(如果机器上没有安装 nuke 的话):
build Clean
与 NewLife.XCode 集成
因为 _build 项目本身就是一个 C# 项目,因此可以直接引用 NewLife.XCode 的类库:
dotnet add package NewLife.XCode
要实现从模型文件生成实体可以使用以下代码:
static void BuildEntity(String modelFile, ILog log)
{
XTrace.WriteLine("正在处理:{0}", modelFile);
PathHelper.BasePath = Path.GetDirectoryName(modelFile);
var options = new EntityBuilderOption();
var tables = ClassBuilder.LoadModels(modelFile, options, out var attrs);
EntityBuilder.FixModelFile(modelFile, options, attrs, tables);
if (string.IsNullOrWhiteSpace(options.Output))
{
options.Output = Path.GetDirectoryName(modelFile);
}
else
{
options.Output = Path.Combine(Path.GetDirectoryName(modelFile), options.Output);
}
EntityBuilder.BuildTables(tables, options, log);
}
不言自明:
modelFile 参数代表 XML 模型文件的全路径。
log 参数代表日志对象,直接传入 XTrace.Log 即可。
实现 Entity 构建目标
NukeBuild 类型有一个静态 RootDirectory 属性代表项目的根目录(就是 build 脚本所在的目录)。我们可以新建一个 Entity 构建目标,在构建过程中扫描所有子目录下的模型文件,并依次调用 BuildEntity 方法即可。
Target Entity => _ => _
.Executes(() =>
{
RootDirectory.GlobFiles("**/*.xml")
.ForEach(path =>
{
var txt = File.ReadAllText(path);
if (!txt.Contains("<Tables") && !txt.Contains("<EntityModel")) return;
BuildEntity(path, XTrace.Log);
});
});
执行 Entity 构建:
nuke Entity
或
build Entity
构建结果如下:
PowerShell Desktop version 5.1.19041.4648
Microsoft (R) .NET SDK version 8.0.303
███╗ ██╗██╗ ██╗██╗ ██╗███████╗
████╗ ██║██║ ██║██║ ██╔╝██╔════╝
██╔██╗ ██║██║ ██║█████╔╝ █████╗
██║╚██╗██║██║ ██║██╔═██╗ ██╔══╝
██║ ╚████║╚██████╔╝██║ ██╗███████╗
╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
NUKE Execution Engine version 8.0.0 (Windows,.NETCoreApp,Version=v8.0)
╬═══════════
║ Entity
╬══
19:19:37.203 1 N - NewLife.Core v10.10.2024.0701 Build 2024-07-01 .NET 8.0
19:19:37.204 1 N - NewLife组件核心库 ©2002-2024 NewLife
19:19:37.205 1 N - _build v1.0.0 Build 2000-01-01 .NET 8.0
19:19:37.205 1 N - _build
19:19:37.206 1 N - 正在处理:D:\src\coderbusy.com\nuke_xcode\src\HiXCode\Model.xml
19:19:37.213 1 N - XCode v11.13.2024.0701 Build 2024-07-01 .NET Standard 2.1
19:19:37.214 1 N - NewLife数据中间件 ©2002-2024 NewLife
19:19:37.215 1 N - 当前配置为输出SQL日志,如果觉得日志过多,可以修改配置关闭[Config/XCode.config:ShowSQL=false]。
19:19:37.237 1 N - 生成实体类 D:\src\coderbusy.com\nuke_xcode\src\HiXCode\Entity
19:19:37.241 1 N - 生成 Group 知识组 {"BaseClass":"Entity","Namespace":"HiXCode.Entity"}
19:19:37.248 1 N - 生成 Group 知识组 {"BaseClass":"Entity","Namespace":"HiXCode.Entity"}
═══════════════════════════════════════
Target Status Duration
───────────────────────────────────────
Entity Succeeded < 1sec
───────────────────────────────────────
Total < 1sec
═══════════════════════════════════════
Build succeeded on 2024/7/22 19:19:37. \(^ᴗ^)/
结语
对于笔者来说,XCode 不是一个新东西,但 Nuke 就比较陌生了。虽然 XCode 目前已经有多种方式可以用来生成实体类,但在接触了 Nuke 以后我立马想到可以将这两者进行集成。借助 Nuke 搭建好的脚手架,我们将获得以下好处:
支持跨平台
无需安装额外的工具(除了初始化 Nuke 时,其他情况下是不要求系统中安装有 Nuke 的)。
没有版本问题,生成器的版本可以和项目使用的主版本一致。
为了便于大家理解,我做了一个小 Demo 放在 Gitee 上,开源地址是:
https://gitee.com/coderbusy/nuke_xcode