BitzOrcas.Modern 的组合根是 src/Hosts/BitzOrcas.Api/Program.cs。它有意保持显式——每个注册调用都可见,没有自动发现魔法,没有基于约定的扫描来隐藏装配失败。四个注册阶段,每个都有明确的职责:
var builder = WebApplication.CreateBuilder(args);
// 1. 跨宿主默认配置(OTel + 健康检查)builder.AddServiceDefaults();
// 2. 核心运行时(上下文、时钟、审计、多租户、占位适配器)builder.Services.AddBitzOrcasCoreRuntime();
// 3. 持久化适配器(SqlSugar/EfCore —— 按配置条件激活)builder.Services.AddBitzOrcasPersistenceAdapters();
// 4. 认证(JWT/HMAC/ApiKey)builder.Services.AddBitzOrcasAuthentication();
// 5. API 管道(Mediator + Mapster + JSON + OpenAPI + RateLimiter)builder.Services.AddBitzOrcasApiPipeline();
var app = builder.Build();app.MapBitzOrcasEndpoints();await app.RunAsync();四个注册阶段
1. AddServiceDefaults() — 跨宿主默认配置
注册在 BitzOrcas.ServiceDefaults 中。这是注册 OTel 的唯一位置——各个宿主不能独立调用 AddOpenTelemetry()。注册内容:
- 链路追踪:ASP.NET Core + HttpClient + 自定义 BitzOrcas ActivitySources
- 指标:ASP.NET Core + HttpClient + Runtime
- 导出器:OTLP(gRPC)到
OTEL_EXPORTER_OTLP_ENDPOINT(默认localhost:4317) - 资源属性:
service.name、service.version、deployment.environment - 健康检查:带
LivenessTag的self检查
2. AddBitzOrcasCoreRuntime() — 横切上下文
注册每个宿主需要的基础服务:
ISystemClock/FixedClock— 确定性时间ICurrentUser/AnonymousCurrentUser— 统一调用者模型(Api 使用 JWT 填充,JobHost 使用匿名)ITenantContext/ITenantResolver— 8 级租户解析链IUnitOfWork/NullUnitOfWork— 占位,由持久化适配器覆盖- 7 个审计接收器(全部为
Null*AuditSink默认值)——由生产审计覆盖 IFileStorage/LocalFileStorage— 本地文件系统默认INotificationPublisher/NullNotificationPublisher— 占位IAppCache/FusionCacheAppCache— 缓存ICorrelationContext— 关联 ID 传播- Mapster 全局配置扫描
3. AddBitzOrcasPersistenceAdapters() — ORM 适配器覆盖
条件注册:仅在同时配置了 ConnectionStrings:Default 和 RabbitMq:Host 时激活。激活后,用生产适配器覆盖 Null/InMemory 默认值:
| 服务 | 默认值(CoreRuntime) | 生产覆盖 |
|---|---|---|
IUnitOfWork | NullUnitOfWork | SqlSugarUnitOfWork 或 CapSqlSugarUnitOfWork |
IAuditLogStore | UnavailableAuditLogStore(快速失败) | SqlSugarAuditLogStore |
IFileAssetRepository | InMemoryFileAssetRepository | SqlSugarFileAssetRepository |
ITicketRepository | InMemoryTicketRepository | SqlSugarTicketRepository |
ICatalogRepository | InMemoryCatalogRepository | SqlSugarCatalogRepository |
| …(所有平台端口) | InMemory* / Null* | SqlSugar* |
4. AddBitzOrcasAuthentication() — 多 Scheme 认证
三种互斥的认证方案:
| Scheme | Handler | 用途 |
|---|---|---|
| JWT Bearer | Microsoft.AspNetCore.Authentication.JwtBearer | 用户认证 |
| HMAC | HmacAuthenticationHandler | 外部应用认证(Nonce 防重放) |
| ApiKey | ApiKeyAuthenticationHandler | API 密钥认证(SHA-256 哈希) |
5. AddBitzOrcasApiPipeline() — Mediator + API 表面
- Mediator 3 源代码生成分发
- Mapster 对象映射
- JSON 序列化选项
- OpenAPI + Scalar UI
- ProblemDetails(RFC 9457)
- 速率限制器(3 种策略:TokenBucket、SlidingWindow、FixedWindow)
中间件管道
在 Program.cs 中显式排序,永不提取到辅助方法:
UseExceptionHandler(ProblemDetails) → CorrelationIdMiddleware → UseAuthentication → DelegationTokenMiddleware → TenantResolutionMiddleware → RequestAuditMiddleware → UseAuthorization → UseRateLimiter → Endpoints排序规则:
- CorrelationId 在一切之前。 每行日志、每个链路追踪 span 和每条审计记录都携带关联 ID。
- 认证在租户解析之前。 租户解析需要来自认证用户的 Claims。
- 租户解析在请求审计之前。 审计信封需要租户上下文。
- 速率限制在授权之后。 未认证流量不应消耗速率限制配额。
Schema 初始化模式
API 支持 CLI 驱动的 schema 初始化——在 web 管道启动前触发:
| 参数 | 行为 |
|---|---|
--init-schema | 创建表(CodeFirst)、创建审计分表、填充 14 个平台系统表 |
--seed-demo | 与 --init-schema 相同 |
--seed-only | 仅填充数据(不创建 schema) |
--no-seed | 仅创建 schema(不填充数据) |
当任何初始化参数存在时,宿主执行 schema 初始化并退出而不启动 web 管道。这就是首次运行体验的工作方式。
两种宿主配置
| 宿主 | 用途 | 认证 | 多租户 | Trim |
|---|---|---|---|---|
| BitzOrcas.Api | HTTP API | JWT + HMAC + ApiKey | 8 级链 | 是(SqlSugar 路径) |
| BitzOrcas.JobHost | 后台作业 | 无 | 无(AnonymousCurrentUser) | 否(Quartz) |
JobHost 使用最小核心运行时——时钟、匿名用户、审计、存储。无认证、无租户解析、无速率限制。ICurrentUser 解析为 CallerType.System 的 AnonymousCurrentUser。
相关
- 模块化单体 — 模块治理系统
- 垂直切片 — 特性如何组织
- ORM 适配器模式图 — 可视化适配器切换图
- Mediator 管道图 — 可视化管道流程