Skip to content
bitzorcas
中EN

Concept

生成结果、Profile 与组合证据

解剖原生模板生成的 Consumer Solution、Host 组合根、Business Starter、商业包闭包、manifest、plan 与所有权边界。

Last updated

[!TIP] 本页解剖 dotnet new bitzorcas-host 模板矩阵的生成结果。从零建新工程优先考虑 bitz 脚手架;两通道以同一已验证消费者工程为契约基线。

模板输出是一份客户拥有的 Solution 加商业包消费闭包。本文以 default-business-multi + sqlsugar 生成的 Acme.ServiceDesk 为主例,并标出 Mini、Single 与扩展 Profile 的差异。

所有权边界

Consumer 仓库

Hosts

Business Starter 源码

Unit / Architecture Tests

Manifest / Plan / Lock Files

商业 Feed

Profile / Framework / Workflow / Licensing

Generators / ORM / Platform / Industry

客户可以修改 Host 与 Starter Module,但必须继续遵守生成的架构测试。Framework、Platform、Workflow、Licensing 和 Generator 以 NuGet 包进入,不应复制源码后本地分叉。

Multi Business 目录

Acme.ServiceDesk/
├── Acme.ServiceDesk.slnx
├── Directory.Build.props
├── Directory.Build.targets
├── Directory.Packages.props
├── NuGet.Config
├── README.md
├── composition-manifest.json
├── composition-manifest.schema.json
├── composition-plan.json
├── src/
│ ├── Hosts/
│ │ ├── Acme.ServiceDesk.Api/
│ │ │ ├── Authentication/
│ │ │ ├── Composition/
│ │ │ ├── Configuration/
│ │ │ ├── Schema/
│ │ │ ├── Tenancy/
│ │ │ ├── Program.cs
│ │ │ └── appsettings*.json
│ │ ├── Acme.ServiceDesk.AppHost/
│ │ └── Acme.ServiceDesk.ServiceDefaults/
│ └── Modules/Business/Starter/
│ ├── Acme.ServiceDesk.Modules.Business.Starter.Contracts/
│ └── Acme.ServiceDesk.Modules.Business.Starter.Application/
└── tests/
├── Acme.ServiceDesk.Unit.Tests/
└── Acme.ServiceDesk.Architecture.Tests/

输出没有 JobHost、前端项目、部署 YAML、维护脚本或底座产品源码。某个文件未生成,先核对 Profile 合同,不要假设生成中断。

三种基础输出差异

项目/能力Mini API SingleDefault Business SingleDefault Business Multi
API✓✓✓
ServiceDefaults✓✓✓
Unit / Architecture Tests✓✓✓
Business Starter Contracts/Application—✓✓
AppHost——✓
Tenancy contractfixed tenant contextfixed tenant contextauthenticated tenant_id claim
Deploymentnonenoneaspire
SQL Server 开发编排——AppHost

Mini Development Shell 可不连接 SQL Server 运行;Business Profile 需要真实数据库合同。Single Profile 由部署 Runbook 提供连接串并执行 Schema,Multi Profile 由 AppHost 在开发环境编排。

API Host 是组合根

Program.cs 负责:

  • 配置失败关闭校验;
  • ServiceDefaults、Problem Details、Forwarded Headers 与 OpenAPI;
  • CurrentTenant、CurrentUser 和 Persistence execution context;
  • 编译期生成的 Module、Endpoint 与 ORM Adapter 注册;
  • Mediator pipeline、License、JWT 与 Authorization;
  • Health、Tenant middleware 与 Endpoint 映射;
  • Schema 或平台运维命令的进程入口。

业务规则不应进入 Host。Host 只组合客户模块和商业包:

Terminal window
rg -n 'AddBitzOrcas|MapBitzOrcas|MapAllGeneratedEndpoints|UseBitzOrcasModules' \
src/Hosts/Acme.ServiceDesk.Api/Program.cs

SqlSugar 与 EF Core 输出的 Program.cs 不同;选中 Provider 的注册是物理代码,不是运行时读取 manifest 后决定。API 与 AppHost 两条接线的真实 rg 命中:

bitzorcas-host session
$ 
68: typeof(TenantSurfaceRestrictionPipelineBehavior<,>),
79:builder.Services.AddBitzOrcasSqlSugar(options =>
137:app.UseBitzOrcasModules();
138:app.MapAllGeneratedEndpoints();

AppHost 的顺序保证

Multi 输出中的 AppHost:

  1. 创建 SQL Server 与 PrimaryDatabase;
  2. 创建一次性 API 项目资源 schema-migrator;
  3. 传入 --migrate-schema apply 并等待数据库;
  4. 启动常驻 API,注入数据库与 Persistence identity;
  5. 用 WaitForCompletion(schemaMigrator) 阻止迁移失败后的 API 启动。
Terminal window
rg -n 'AddSqlServer|AddDatabase|schema-migrator|WaitForCompletion' \
src/Hosts/Acme.ServiceDesk.AppHost/Program.cs

Authorization Multi Profile 还增加 RabbitMQ 与 authorization-bootstrap。其他 Multi Profile 不应出现这些资源。

Business Starter 是完整垂直切片

Contracts 项目中的 WorkItem 是统一聚合根和持久化事实模型:

  • 继承 TenantAggregateRoot<string>;
  • [BitzTable] 声明租户与软删除;
  • [BitzColumn] 定义标题约束;
  • 公开无参构造仅供 ORM 物化,业务创建只能走 Create;
  • 标题空白、超过 160 字符或租户无效时返回稳定错误。

Application 项目中的 CreateWorkItemCommand:

  • 用 [GenerateEndpoint] 生成 POST /api/work-items;
  • 实现 IAuthorizedRequest,声明资源与 Create 动作;
  • Handler 从可信 ICurrentTenant 获取租户;
  • 直接使用 ICommandRepository<WorkItem,string> 保存聚合;
  • 事务、DI、Endpoint 和 ORM Adapter 由生成式管线接线。
Terminal window
rg -n 'BitzTable|TenantAggregateRoot|GenerateEndpoint|ICommandRepository' \
src/Modules/Business/Starter

不要为同一事实再创建 Entity、Mapper、MappingSpec、DataPort 或 Infrastructure 项目。这会破坏统一聚合路径,并被架构门禁识别。

商业包与中央版本

Directory.Packages.props 统一管理商业包版本,NuGet.Config 固定 Feed source mapping。API 通过 Profile 包获取基线闭包:

输出Profile 包ORM 包
MiniBitzOrcas.Profile.Mini.ApiSqlSugar 或 EF Core 对应 Infrastructure
BusinessBitzOrcas.Profile.Default.BusinessSqlSugar 或 EF Core 对应 Infrastructure

Business Starter Contracts 只依赖 Domain、Persistence Metadata 与 Generator;Application 依赖 Application、Modularity 以及条件性 Industry 包。项目引用方向保持 Host → Application → Contracts。

composition-manifest.json

Manifest 是最终组合事实,当前 schemaVersion=2。主要字段:

字段用途
profileChoice/profileId/profilePackageId公开选择与商业 Profile
runtimeAdapter实际 ORM
tenancy/deployment请求隔离与运行拓扑
platformModule/industryExtension条件闭包
hosts/projects物理 Solution 成员
modules/capabilitiesModule、Endpoint、Job、租户合同
packages/packageReferences/projectReferences依赖闭包和方向
generators/endpointAssemblies/jobAssemblies编译期发现面
licenseFeaturesRuntime License 需求
verification生成版本建议的验证命令
excluded明确未选择的能力
Terminal window
# 先确认 Schema、Profile 与 ORM 版本字段。
# 再审阅运行成员、License 需求和明确排除项。
jq '{
schemaVersion,
profileChoice,
runtimeAdapter,
hosts,
modules,
capabilities,
licenseFeatures,
excluded
}' composition-manifest.json

Manifest 不读取运行时状态,也不证明 Feed Token、License、数据库或业务配置有效。

composition-plan.json

Plan 是物理输出清单,当前 schemaVersion=1:

  • selectedProjects:应进入 Solution 的项目;
  • selectedEndpoints / selectedJobs:该 Profile 声明的入口;
  • writeFiles:原生模板应写入的文件;
  • removePaths:当前分支需要删除的路径。
Terminal window
# selected 字段描述生成选择,writeFileCount 描述物理写入面。
# removePaths 应与当前 Profile 的条件裁剪一致。
jq '{
schemaVersion,
selectedProjects,
selectedEndpoints,
selectedJobs,
writeFileCount: (.writeFiles | length),
removePaths
}' composition-plan.json

Plan 不是重新执行脚本的输入。修改 Plan 不会增加项目、包或 Endpoint;需要另一组合时,从精确模板版本重新生成到空目录。

Platform Profile 的增量

Authorization 输出会增加:

  • BitzOrcas.Platform.Authorization 及对应 Provider/CAP 接线;
  • platform.authorization License feature;
  • Authorization schema/operations command;
  • Platform adoption tests;
  • Multi AppHost 的 RabbitMQ、Schema 后 bootstrap 和独立操作身份。

MasterData 输出增加 MasterData 运行时包、Provider、License feature 与采用测试,但不会增加 Authorization 的 RabbitMQ/bootstrap 文件。

这些实现仍来自商业包;Consumer 只拥有 Host 接线和采用证据。

Industry Profile 的增量

Finance、HR、Auction、Legal Profile 在 Starter Application 中增加对应行业扩展包和能力标识,并保留 IndustryExtensionAdoptionTests。行业扩展不会生成新的行业业务模块源码;客户需要基于包合同建立自己的 Owner Module。

检查最终闭包时以 manifest 为准,因为 Auction 或 Legal 可能因依赖关系同时包含 Finance 包。

测试项目

Unit Tests 检查 Result、License composition、Profile/ORM、Schema、Starter Aggregate 和条件扩展采用。Architecture Tests 检查:

  • Consumer 不复制 Framework/Platform 源码;
  • Application 不依赖 ORM/Host;
  • 聚合不变量留在聚合;
  • Owner private 类型不泄漏到公开合同;
  • Handler 与 Endpoint 保持切片本地;
  • Module/Host 项目引用与生成式接线符合边界。
Terminal window
dotnet test tests/Acme.ServiceDesk.Architecture.Tests \
--configuration Release

这些测试是客户仓库后续修改的持续门禁,不是只在生成当天运行一次。

扩展位置

需求应修改/新增的位置不应修改的位置
新业务不变量Owner Module 的 AggregateAPI Program.cs
新用例同一 Module 的 Command/Query + Handler通用 Framework
新 Endpoint用例上的生成属性手写全局路由注册
新持久化字段统一聚合元数据 + Schema平行 Entity/Mapper
采用 Platform/IndustryHost 接线、Owner 合同与测试手改 manifest 假装已采用
升级商业包中央版本 + 锁文件 +升级证据复制商业包源码

另见

100%

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