Skip to content
bitzorcas
中EN

Guide

代码生成器

用 bitz-codegen 的 business-slice 生产入口生成行业中立统一聚合切片,理解原子落位、BOCG 错误码族、manifest 证据字段,以及旧输入审计入口的失败关闭语义。

Last updated

BitzOrcas.CodeGeneration.Cli(命令名 bitz-codegen)是唯一承担”业务切片脚手架”职责的生成工具,也是仅有的两个 PackAsTool 打包工具之一。它的生产入口只有一个:--business-slice <schema.json>,从一份严格校验的 JSON 切片定义生成 Contracts、Application、行为测试与裁剪冒烟骨架。

历史的 --inline/--module/--use-case 三种自由输入并没有被删除,但已经降级为审计入口:它们不生成任何 C#,只向 .codegen-output/ 写一份 productionReady=false 的诊断清单并以退出码 2 结束。如果你按老教程敲出的命令得到了 0 个源文件,这不是 bug,是失败关闭在工作。

工具身份与安装

Terminal window
# 商业 Feed 本地安装为 dotnet tool(与 bitz-upgrade 同一发布通道)。
dotnet new tool-manifest
dotnet tool install BitzOrcas.CodeGeneration.Cli \
--version 1.0.0-alpha1 \
--add-source <commercial-feed>
# 未安装时也可从仓库源码运行。
dotnet run --project src/Tooling/BitzOrcas.CodeGeneration.Cli -- --help

帮助文本属于模板合同的一部分:verify-template.sh 会断言内部派生选择器不出现在 help 中,回归时以 help 快照为准。

生产入口:business-slice

一条命令的真实效果(schema 取自仓库测试夹具同构的 service-requests.v1.json,输出为真实运行截取):

bitz-codegen session
$ 
✔ 校验切片 schema(schemaVersion 1)完成
模块: ServiceRequests
状态: 成功
模板版本: 1.0.0
模式: 已写 manifest
输出目录: .codegen-output/ServiceRequests
文件数: 15
[written] Build Directory.Build.props
[written] Build Directory.Packages.props
[written] Solution ServiceRequests.Generated.slnx
[written] Documentation README.md
[written] Contracts.Project src/Example.Modules.ServiceRequests.Contracts/Example.Modules.ServiceRequests.Contracts.csproj
[written] Contracts src/Example.Modules.ServiceRequests.Contracts/ServiceRequestsContractAssembly.Generated.cs
[written] Contracts.Errors src/Example.Modules.ServiceRequests.Contracts/ServiceRequestsErrors.Generated.cs
[written] Domain src/Example.Modules.ServiceRequests.Contracts/ServiceRequest.Generated.cs
[written] Application.Project src/Example.Modules.ServiceRequests.Application/Example.Modules.ServiceRequests.Application.csproj
[written] Application.Composition src/Example.Modules.ServiceRequests.Application/ServiceRequestsModule.Generated.cs
[written] Application.ApplicationCommand src/Example.Modules.ServiceRequests.Application/Commands/ServiceRequests/OpenServiceRequestCommand.Generated.cs
[written] Tests.Project tests/Example.Modules.ServiceRequests.GeneratedTests/Example.Modules.ServiceRequests.GeneratedTests.csproj
[written] Tests.Behavior tests/Example.Modules.ServiceRequests.GeneratedTests/ServiceRequestGeneratedBehaviorTests.Generated.cs
[written] TrimSmoke.Project samples/Example.Modules.ServiceRequests.TrimSmoke/Example.Modules.ServiceRequests.TrimSmoke.csproj
[written] TrimSmoke samples/Example.Modules.ServiceRequests.TrimSmoke/Program.cs
非法 BOCG3xx合法IO 失败

business-slice schema v1

编译期严格校验

零写入退出

写入临时目录

Directory.Move 原子落位

manifest Status=ready

人工接 slnx / 模块治理 / 门禁

删除临时目录 BOCG310
目标目录保持原样

切片 Schema 固定行业中立形态:一个必填租户的统一聚合加单条 Create 命令,主键由客户端分配 Guid;domainEvents 与 integrationEvents 数组必须显式声明为空。以下是仓库测试夹具同构的法律科技示例:

matter-intakes.v1.json
{
"schemaVersion": 1,
"frameworkVersion": "1.0.0-alpha1",
"module": {
"name": "LegalCases",
"baseNamespace": "BitzOrcas.Platform.LegalCases",
"description": "民商事案件模块",
"code": "legal-cases",
"featureCode": "legal-cases.create"
},
"aggregate": {
"name": "MatterIntake",
"pluralName": "MatterIntakes",
"description": "租户内待合伙人审批的立案申请",
"tableName": "GeneratedMatterIntake",
"idType": "guid",
"idAllocation": "client",
"tenancy": "required",
"softDelete": true,
"concurrency": true,
"fields": [
{
"name": "CaseNumber",
"description": "法院或仲裁案件编号",
"type": "string",
"required": true,
"maxLength": 64,
"normalize": "trim",
"errorMember": "MatterIntakeInvalidCaseNumber",
"errorCode": "LegalCases.MatterIntake.InvalidCaseNumber"
},
{
"name": "DisputeAmount",
"description": "争议标的金额",
"type": "decimal",
"required": false,
"minimum": 0,
"maximum": 100000000000,
"normalize": "none",
"errorMember": "MatterIntakeInvalidDisputeAmount",
"errorCode": "LegalCases.MatterIntake.InvalidDisputeAmount"
}
]
},
"create": {
"commandName": "SubmitMatterIntakeCommand",
"description": "在当前租户内提交立案申请",
"route": "/api/matter-intakes",
"resourceType": "matter-intake",
"permissionMember": "SubmitMatterIntake",
"permissionCode": "legal-cases.matter-intake.create",
"tenantErrorMember": "TenantRequired",
"tenantErrorCode": "LegalCases.Tenant.Required"
},
"domainEvents": [],
"integrationEvents": []
}

每个字段的 errorMember/errorCode 强制成对出现——生成的校验规则直接携带强类型错误码,防止”裸字符串返回”。调用方式:

Terminal window
dotnet bitz-codegen --business-slice ./design/matter-intakes.v1.json \
--output .codegen-output

目标目录已存在会直接拒绝覆盖;没有 OverwriteStrategy 可配。想要重新生成,先清掉上一次产物并核对差异。

Manifest 与证据字段

一次成功生成结束时 manifest 记录的不只是文件清单:

字段含义
Statusready 或 blocked;blocked 不是失败,而是带诊断的可审阅结果
ProductionReady生产可用标记;审计入口恒为 false
SchemaSha256输入切片的哈希,锁定”这次生成对应哪份定义”
SourceGeneratorOwned归源生成器拥有的接线清单:dependency-injection、endpoint、orm-fluent-configuration、module-catalog
ExplicitlyUnsupportedv1 明确不支持的形态:update-command、query、domain-event、integration-event

SourceGeneratorOwned 解释了为什么生成物里看不到 DI 注册和 Endpoint 文件——那些由 Roslyn 源生成器在编译期接管,手写只会引入第二份事实。写入采取两阶段:临时目录整体写完后 Directory.Move 原子落位,IO 失败时删除临时目录并报 BOCG310,目标目录保持字节不变。

审计入口:失败关闭的旧形态

三种历史输入仍然可用,但角色变了:

Terminal window
# 这是合法命令吗?不是生产路径:它会写审计清单然后退出 2。
dotnet bitz-codegen --inline \
--module-name Tracker \
--aggregate MatterIntake \
--property 'CaseNumber:string:64' \
--property 'DisputeAmount:decimal'
echo $? # 2;.codegen-output 里只有 manifest,没有任何 C#
旧入口当前行为
--module <json>(聚合模式)写 productionReady=false 诊断清单,退出 2
--inline --module-name … --aggregate …同上
--module … --use-case …(用例模式)同上
--with-endpoint明确拒绝,不再生成手写端点
--dry-run / --no-staging所有入口均拒绝;工具绝不直写源码树

这些入口的存在价值是让历史脚本、课件和老 README 得到确定性的”已被时代淘汰”反馈,而不是悄悄产出不符合当前架构的半成品。

错误码族

族语义共同点
BOCG1xx / BOCG2xx旧输入审计(如上文三个入口)零 C# 输出
BOCG3xx生产 schema 校验失败零写入

自动化判断只用两个信号:进程退出码与 manifest 的 ProductionReady 字段;不要解析人类可读文案。

人工落地流程

  1. 在设计评审中确认业务键、权限码({module}.{resource}.{action})、错误码归属后再写 schema——schema 即契约,进入 SchemaSha256 证据链。
  2. 运行生成,检查目标目录与 manifest 的 ready/ProductionReady=true。
  3. 把生成项目接入 Consumer Solution:加入 .slnx,由 owner 目录的 [AppModule] 标记与 DependsOn 收编治理关系。
  4. 为行为测试补真实 fixture 与断言;切片自带 trim smoke,确认它在 CI 的裁剪矩阵中执行。
  5. 补齐 XML 注释与数据范围规则后,运行 Application、Architecture 与 Integration 门禁。
  6. 删除 .codegen-output 暂存副本;生成目录即唯一事实。

验证命令

Terminal window
# 生成器模板、原子落位与 manifest 合同。
dotnet test tests/BitzOrcas.CodeGeneration.Tests --configuration Release
# 生成器作为包被隔离项目消费的合同。
dotnet test tests/BitzOrcas.Generator.Package.Tests --configuration Release

tests/BitzOrcas.CodeGeneration.Tests/Fixtures/service-requests.v1.json 是官方夹具:本页示例的字段结构与其逐一对应。遇到 schema 行为不确定时以该夹具和它的断言为准,不要靠猜。

常见错误

  • 把旧教程里的 --inline 流程当生产路径,拿到退出码 2 才发现世界变了;
  • 目标目录残留上次生成物导致整体拒绝;
  • 期待生成器产出 update/query 或领域事件——ExplicitlyUnsupported 白纸黑字写着不支持;
  • 事件数组省略而不是显式置空;
  • 把 blocked 清单当失败静默重跑,而不读诊断定位 schema 问题。

另见

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%