不是所有域都严格遵循三层包模式。代码中实际存在六个结构变体。理解它们有助于避免”一刀切”思维。
变体 A:单体包(Sms 域)
Sms 是唯一不拆包的成熟域。6 家供应商(Aliyun / Tencent / Huawei / Yunpian / Twilio / Vonage)以子命名空间内嵌在单一包内:
Bitzsoft.Integrations.Sms/├── ISMS.cs ← 抽象接口├── Aliyun/{ AliyunSmsOptions, AliyunSmsService }├── Tencent/{ TencentSmsOptions, TencentSmsService }├── Huawei/ ├── Yunpian/ ├── Twilio/ ├── Vonage/└── ServiceCollectionExtensions.cs ← 全部 6 家 DI 注册没有 .Sms.Aliyun 厂商包,没有 .All 聚合包。DI 方法命名也不带 Bitzsoft 前缀(AddAliyunSms() 而非 AddBitzsoftAliyunSms())。
详见 ADR-0001。
变体 B:嵌套域(Finance 域)
Finance 是”域中有域”——公共基础包下再分三个子域,每个子域各自完整三层:
Finance(公共基础:领域异常 + 通用模型)├── Finance.Invoice(抽象)+ .Baiwang + .Kingdee + .Nuonuo + .Invoice.All├── Finance.Tax(抽象)+ .Tax.QiXiangYun├── Finance.Payroll(抽象)+ .Payroll.All└── Finance.All(总聚合,拉入全部子域)变体 C:适配器模式(LegalDatabase 域)
LegalDatabase 的多数供应商只支持 SSO 跳转访问,API 能力有限。抽象层定义功能标志枚举:
[Flags]public enum LegalDatabaseCapabilities{ None = 0, AccessUrl = 1, // SSO 跳转 Search = 2, // API 搜索 DocumentDetail = 4, // API 文档详情}内置 SsoRedirectLegalDatabaseProvider 适配器——对只支持 SSO 的厂商,委托给共享的 SsoRedirect 域。不支持的 API 直接抛 NotSupportedException。
变体 D:抽象层内含编排引擎(OutboundCall 域)
OutboundCall 的抽象包里除了接口,还有一个 provider-agnostic 的拨号编排引擎:
Bitzsoft.Integrations.OutboundCall/├── IOutboundCallService.cs ← 统一接口├── CampaignDialer.cs ← 编排引擎(节流、暂停/恢复/停止)├── CampaignRuntime.cs ← 运行时└── Models/ ← 活动模型国内厂商(腾讯云等)实现 campaign(预测式外呼)模型,国际厂商(Twilio / Vonage)实现 per-call 模型。两种都实现同一个 IOutboundCallService 接口。
变体 E:细粒度多接口(TeamWork 域)
TeamWork 把协同办公能力拆成 14 个细粒度接口:
public interface ITeamWorkApprovalProvider { ... } // 审批public interface ITeamWorkMessageProvider { ... } // 消息public interface ITeamWorkOrgProvider { ... } // 通讯录public interface ITeamWorkCalendarProvider { ... } // 日历public interface ITeamWorkDocumentProvider { ... } // 文档// ... 共 14 个每个厂商只实现和注册真实能力。飞书额外提供日历与文档,企业微信提供客户联系,泛微当前只暴露工作流与健康检查。致远和蓝凌在获得正式契约前只进入 Catalog,不伪装成可调用能力。
变体 F:双接口(Express 域)
Express 有两个并行接口:
| 接口 | 覆盖场景 |
|---|---|
IExpressProvider | 通用物流轨迹 / 寄件 / 面单 |
ISfLegalDocumentProvider | 顺丰函证通法律函件全生命周期 |
法律函件业务语义和通用物流差异太大,强行塞进一个接口不合适。
变体对照表
| 变体 | 代表域 | 核心特征 | 不拆三层的原因 |
|---|---|---|---|
| A 单体 | Sms | 全部供应商在一个包 | 成熟最早,拆包是破坏性变更 |
| B 嵌套 | Finance | 域中有域 | 子域共享异常和模型 |
| C 适配器 | LegalDatabase | 功能标志 + SSO 委托 | 多数厂商 API 能力有限 |
| D 编排引擎 | OutboundCall | 抽象层含 CampaignDialer | 需要跨厂商编排逻辑 |
| E 细粒度 | TeamWork | 14 个接口 | OA 能力差异大 |
| F 双接口 | Express | 两个并行接口 | 业务语义差异大 |