Skip to content
bitzorcas
中EN

Guide

Tool Connectors 组合根、配置与治理

讲透三类连接器的条件 DI、SDK 前置注册、TryAdd 顺序、权限与 Feature 目录及宿主交付验证。

Last updated

本章讨论连接器“如何进入进程”。当前扩展只绑定 Port 到 Adapter,不负责注册厂商 SDK;顺序、配置与健康验证都属于 Host 组合根。

1. 条件注册算法

否 / 缺失 / 非法是否是

读取 Enabled

严格 bool true?

TryAdd Unavailable

SDK service 已注册?

TryAdd real Adapter

三个连接器独立执行同一算法。bool.TryParse 让缺失或非法值按 false 处理,这是配置层的 fail-closed。

2. 正确的组合顺序

Host 组合示例
// ① SDK 必须先进入 IServiceCollection,条件注册才能看见其 ServiceType。
if (configuration.GetValue<bool>("Connectors:Ocr:Enabled"))
services.AddOCRService(configuration.GetSection("Connectors:Ocr"));
// ② 然后选择 Port 的真实或不可用实现。
services.AddBitzOrcasToolConnectorsAdapters(configuration);
// ③ 启动验证应解析 IOcrPort,并执行不泄露敏感数据的 readiness probe。

源码 XML 示例把 Adapter 注册放在 SDK 之前;若照抄,探测时看不到 SDK,先放入 Unavailable。由于方法使用 TryAddScoped,之后再次调用也不会覆盖早先的 Port 注册。这是文档必须纠正的顺序敏感点。

3. TryAdd 的含义

TryAddScoped<TPort,TAdapter> 保留此前注册。它支持宿主显式替换测试实现,也可能让错误顺序永久保留 unavailable 或第三方实现。

生产组合根应:

  1. 集中注册,避免多个扩展隐式争夺同一 Port;
  2. 在启动测试中断言最终 ImplementationType;
  3. 明确自定义覆盖发生在默认注册之前还是之后;
  4. 不依赖重复调用“修复”先前选择;
  5. 对 Enabled=true 但 SDK 缺失记录结构化启动诊断。

4. 当前 Host 状态

BitzOrcas.Api.csproj 引用 Contracts 是治理可见性安排。源码未引用 Infrastructure,未调用 Tool Connectors DI,也未调用三个 SDK 扩展。

因此当前可以说:

  • 商业包目录可发布 Contracts/Infrastructure;
  • 防腐 Port 和 Adapter 可被其他 Host 复用;
  • 未配置时的 Unavailable 行为有实现;

当前不能说:

  • API Host 已开放连接器;
  • 租户开启 Feature 即可使用;
  • 健康检查证明供应商可达;
  • 权限已经保护了某条路由。

5. 配置与 Feature 分工

层次当前 Key应回答的问题
进程配置Connectors:*:Enabled本实例是否装配 SDK/Adapter
产品 Featuretool-connectors.*哪个租户/用户可使用能力
权限tool-connectors.*.execute哪个角色可执行操作
业务规则owner 状态/审批这次操作是否允许

四层不能互相替代。Enabled=false 应使依赖不可用;Feature=false 应在请求层稳定拒绝;无权限应返回授权错误;业务拒绝应给出领域原因。

6. 治理重复声明

owner-local ToolConnectorsModule 已声明模块、依赖、权限和 Feature。PlatformModuleGovernance.cs 仍保留同名旧声明,且注释与现实不符。

重复来源会带来三类风险:扫描器重复注册、描述/默认值漂移、维护者修改错误位置。建议迁移步骤:

  1. 确认治理扫描能发现 Contracts;
  2. 为模块码、权限码、Feature Key 建唯一性测试;
  3. 删除 Platform 中旧声明;
  4. 更新治理快照和文档;
  5. 在双 ORM/无数据库 Host 下验证目录一致。

7. 密钥与配置安全

Enabled 可放普通配置,供应商凭据不得进入仓库或日志。配置模型应使用 secret provider 引用、启动时校验必需字段并避免 IOptions dump。

iManage 是按租户创建客户端,更需要定义租户到凭据引用的安全映射。Crawler proxy/cookie、OCR 数据目录也应作为运维资产管理,不能由请求任意覆盖。

8. 健康模型

“DI 可解析”只证明有真实或 unavailable 实现。健康应分层:

  • composition:期望的 Adapter 是否被选中;
  • configuration:SDK 的必需配置是否完整;
  • connectivity:供应商是否可达;
  • capability:最小无副作用操作是否成功;
  • dependency state:限流、熔断或凭据是否异常。

Readiness 不应执行上传、签出或打开任意公网 URL。探针必须低成本、可限流且不泄露租户数据。

9. 启动验证示例

验证组合结果
// ① Enabled 来自部署期望,而不是从 Port 类型猜测。
bool expected = configuration.GetValue<bool>("Connectors:Ocr:Enabled");
// ② 从作用域解析,因为 Port 注册为 Scoped。
await using AsyncServiceScope scope = provider.CreateAsyncScope();
IOcrPort port = scope.ServiceProvider.GetRequiredService<IOcrPort>();
// ③ 生产代码宜暴露显式 capability descriptor,避免依赖类型名。
if (expected && port is UnavailableOcrPort)
throw new InvalidOperationException("OCR enabled but adapter unavailable.");

最后一行可用于当前集成测试;正式健康契约应由公共 capability 接口表达,避免 Host 依赖 Infrastructure 内部类型。

10. 发布配置清单

每个连接器的发布说明至少列出:

  • SDK 包版本和兼容矩阵;
  • Enabled 与 Feature 默认值;
  • 必需 secret/config;
  • 网络出口、DNS、代理、证书要求;
  • 超时、并发、速率限制;
  • 数据区域与供应商处理位置;
  • 健康探针和告警;
  • 禁用、回滚和凭据轮换步骤。

11. 组合合同测试

参数化测试应覆盖三连接器 × 四状态:Disabled、Enabled+SDK 缺失、Enabled+SDK 存在、非法配置。另测预注册覆盖和错误调用顺序。

缺少 SDK 时失败关闭
// ① 构造 Enabled=true,但故意不注册 IOCRService。
var services = new ServiceCollection();
var configuration = BuildConfig(("Connectors:Ocr:Enabled", "true"));
// 未调用 AddOCRService。
services.AddBitzOrcasToolConnectorsAdapters(configuration);
// ② Port 可解析,但选择结果必须是 unavailable。
using ServiceProvider provider = services.BuildServiceProvider();
using IServiceScope scope = provider.CreateScope();
var port = scope.ServiceProvider.GetRequiredService<IOcrPort>();
Assert.IsType<UnavailableOcrPort>(port);

12. 源码核查

Terminal window
# ① 检查条件选择、SDK 探测和三个配置键。
rg -n "TryAddScoped|IsSdkServiceRegistered|EnabledKey" \
src/Platform/ToolConnectors -g '*.cs'
# ② 对照治理声明与 Host 组合调用。
rg -n "ToolConnectorsModule|tool-connectors\." src/Platform -g '*.cs'
rg -n "AddBitzOrcasToolConnectorsAdapters" src/Hosts -g '*.cs'

返回 Tool Connectors 总览

100%

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