XiHan Framework 处于预览阶段

查看获取方式
跳转到内容

核心概念 ​

这一页把框架的核心概念一次讲清:特性与清单、能力图谱、执行管道、操作契约、默认实现与 Provider、结果与错误、环层与命名。它是后面所有章节的词汇表。读完第一个应用再读这一页效果最好,因为每个概念你都已经在代码里碰过。

一张图 ​

text
HTTP 请求 / gRPC 调用 / MCP tools/call / 命令行 / 消息投递 / 作业触发 / 插件回调
   │  协议适配器或派发器构造 InvocationContext,把线上消息翻译成操作请求
   ▼
Ingress → Observe → Resilience → Authenticate → Tenant → Authorize
        → Validate → Idempotency → Transaction → Handle → Egress
   │  Handle 阶段执行操作,操作经子系统抽象访问 Provider
   ▼
Egress:Result 与 Error 翻译回协议(HTTP 为 RFC 9457 Problem Details,gRPC 为状态码与尾部元数据)

应用由若干特性组成,特性在启动前被内核装配成一张能力图谱;运行时每次调用都走同一条管道;业务在 Handle 阶段以操作的形式执行;横切能力由子系统提供,子系统的实现可以替换。

特性与清单 ​

特性是实现 IFeature 的类,是内核装配的最小单元。它只有两个成员:一份清单 Manifest,一个 Configure(FeatureContext) 方法。清单写明这个特性是谁、提供哪些能力、依赖哪些能力、贡献了什么;Configure 在构建期被调用一次,用来显式注册服务、中间件、权限与操作。

特性没有基类、没有生命周期钩子,内核也不扫描程序集。应用用 UseFeature<T>() 显式加入每一个特性。需要在启动与停止时做事的特性实现 IHostedFeature。

能力包是包含一个或多个特性的 NuGet 包。框架里每个子系统的默认实现与 Provider 都是能力包;应用自己的业务模块也写成能力包。详见特性与清单。

能力 ID 与能力图谱 ​

依赖按能力声明,不按包名或类型。能力 ID 的形式是 <领域>.<能力>,引用时带接口版本,如 persistence.relational@1、caching.distributed@1。同一能力可以由多个 Provider 提供:persistence.relational 可以来自 Persistence.InMemory、Persistence.EntityFrameworkCore 或 Persistence.SqlSugar。

内核在构建期收集全部清单,按版本范围求解,拓扑排序,生成已解析图。缺失依赖、循环、版本冲突、同一能力有多个候选都会带着双方信息报错;启动日志与 graph 命令打印同一份图。同一能力有多个 Provider 时,默认实现(清单 role: default)自动让位;两个以上显式 Provider 时,在配置里指定。详见能力图谱与 Provider。

执行管道 ​

每次调用都经过一条固定十一个阶段的管道:

阶段职责谁提供中间件
Ingress协议消息归一化、大小限制内核
ObserveTrace、日志、指标、审计内核、审计子系统
Resilience截止时间、限流、并发上限、熔断内核
Authenticate主体解析安全子系统
Tenant租户解析与分片多租户子系统
Authorize权限与策略判定安全子系统
Validate契约校验内核,由操作 Schema 驱动
Idempotency幂等键去重缓存子系统
Transaction工作单元持久化子系统
Handle调用操作内核
Egress结果与错误翻译协议适配器

特性按阶段插入中间件,不需要知道其他中间件。排序规则是「阶段、阶段内的 Before 与 After 约束、归属清单 ID」,结果确定且可打印。管道不绑定 HTTP:Web、命令行、消息消费、作业与插件回调走同一条管道。详见执行管道。

调用上下文 ​

管道上下文是 InvocationContext,携带取消令牌、截止时间、W3C Trace、已登记的 Baggage 键(租户、主体、关联 ID、幂等键、区域)、作用域对象袋与作用域服务。安全上下文(主体、租户)由 Authenticate 与 Tenant 阶段写入,之后不可变。详见调用上下文。

操作契约 ​

业务以操作为单位声明:一个类实现 IOperation<TRequest, TResponse> 并标注 [Operation]。操作 ID 的形式是 <资源复数>.<动词>,如 orders.create。源生成器从契约产出登记代码与请求、响应的 JSON Schema;协议适配器把 HTTP 请求、gRPC 调用、MCP 的 tools/call 与命令行参数翻译成同一种调用。

操作 IDHTTPgRPCMCP tool命令行
orders.createPOST /ordersOrders/Createorders_createorders create
orders.getGET /orders/{id}Orders/Getorders_getorders get
orders.listGET /ordersOrders/Listorders_listorders list

授权要求与错误码在各协议上一致。详见操作契约。

默认实现与 Provider ​

每个子系统有一个抽象包 <领域>.Abstractions,配一个零外部依赖、容量有界的默认实现(InMemory、FileSystem),再由 Provider 包接入 EF Core、SqlSugar、Redis、RabbitMQ、Kafka、S3 等外部设施。

角色包名形式示例
抽象<领域>.AbstractionsCaching.Abstractions
默认实现按机制命名Caching.InMemory、ObjectStorage.FileSystem
经持久化子系统的 Provider<领域>.DatabaseSecurity.Database
接外部设施的 Provider按技术命名Caching.Redis、Persistence.EntityFrameworkCore
一致性套件<领域>.ConformanceCaching.Conformance

「默认」是清单里的角色,不是包名。换 Provider 只加包、加一行 UseFeature,业务代码不变;默认实现与 Provider 通过同一套一致性套件。

结果与错误 ​

可恢复的失败用 Result 与 Error 表达,不抛异常。错误码的形式是 <领域大写>_<KIND>_<三位序号>,如 PERSISTENCE_CONFLICT_001、SECURITY_DENIED_004;KIND 决定 HTTP 状态码、gRPC 状态与命令行退出码。Error 只携带消息键与参数,宿主在 Egress 阶段按调用方的区域翻译成文案。配置与编程错误才抛异常。详见结果与错误处理。

本地化 ​

面向人的文案不写在代码里。代码只引用消息键常量,每种语言一个文件 Localization/<区域>.json,内置十种区域,默认 en-US。取文案用 key.L(),按当前调用的区域渲染。详见全球化和本地化。

环层与依赖规则 ​

包按环层组织,依赖只能指向更低的环,同环之间只经抽象包往来,规则由架构测试执行:

text
Ring 6  组合包          Profiles.Minimal / Standard / Full
Ring 5  协议与插件      Protocols.* / Plugins.InProcess / OutOfProcess / Wasm
Ring 4  宿主            Hosting.AspNetCore / Hosting.CommandLine
Ring 3  实现            <领域>.InMemory、<领域>.Database、Redis、EntityFrameworkCore 等
Ring 2  抽象            Domain、<领域>.Abstractions
Ring 1  内核            Kernel
Ring 0  原语层          Primitives
工具链                  Kernel.Analyzers、Kernel.Generators、Persistence.Generators、
                        <领域>.Conformance、Testing、Cli

原语层不引用任何包;内核与全部抽象包只允许 Microsoft.Extensions.* 抽象包;原语层与内核零反射,反射只允许出现在 Plugins.InProcess。

命名约定 ​

命名由术语表推出,架构测试校验:

对象规则示例
包 IDXiHan.Framework.<领域>[.<角色>]XiHan.Framework.Caching.Redis
命名空间等于包 ID,子命名空间最多一层XiHan.Framework.Caching.Abstractions.Locking
能力 ID<领域小写>.<能力>,引用时带接口版本caching.distributed@1
清单 IDxihan.<领域>.<名称>xihan.caching.redis
配置节XiHan:<领域>XiHan:Caching
错误码<领域大写>_<KIND>_<三位序号>PERSISTENCE_CONFLICT_001
操作 ID<资源复数>.<动词>orders.create
消息键<领域>.<资源>.<键>security.token.subject_missing

类型名不带 XiHan 前缀;Default、Core、Common、Manager、Helper 等词不进包名与领域名。

稳定性分级 ​

公开类型都带 [ApiLevel(Stability, <引入版本>)],公开面以各包的 PublicAPI.Shipped.txt 与 PublicAPI.Unshipped.txt 为准:

级别含义
Stable大版本内不破坏
Preview可能变更
Experimental可能移除,用于收集反馈
Internal不对外承诺,分析器阻止外部引用
Deprecated将在下一个大版本移除

下一步 ​

Released under The MIT License