来源：https://framework.docs.xihanfun.com/appendix/why

# 为什么是曦寒

.NET 上不缺应用框架。这一页回答两个问题：XiHan Framework 解决了哪些别的框架没解决好的问题，以及为此你要付出什么代价。它是选型说明，适合正在评估后端框架的团队；已经决定使用的读者可以直接去[入门指南](/getting-started/installation)。

## 先说结论

| 情况 | 建议 |
| --- | --- |
| 中大型、长期维护、多人协作的 .NET 后端，重视依赖边界与可替换性 | 适合 |
| 多租户 SaaS、企业中后台，需要租户、权限、审计、工作流、调度这类通用能力 | 适合 |
| 同一业务要同时提供 REST、gRPC、MCP tool 或命令行 | 适合 |
| 需要第三方用其他语言写插件，或要求插件崩溃不拖垮宿主 | 适合 |
| 目标是 Native AOT 发布或冷启动敏感的服务 | 适合，非 AOT 的 Provider 需替换或接受 JIT |
| 短期项目，只要几个 CRUD 接口 | 直接用 ASP.NET Core 最小 API 更省事 |
| 必须马上上生产、需要正式版 | 框架仍是预览版，见本页末尾的「当前限制」 |

## 五个痛点与解法

### 依赖关系到运行时才知道

多数模块化框架把依赖写在模块特性或基类上，谁依赖谁、缺了什么、版本是否匹配，要跑起来才知道。这里每个特性带一份清单，按能力 ID 声明依赖：

```text
xihan.persistence.inmemory <版本> (default)
  provides persistence.relational@1
  requires kernel.hosting@1 -> xihan.kernel.core
```

内核在构建期求解全部清单，缺失依赖、循环、版本冲突、同一能力多个候选都会带着双方信息报错；启动日志与 `graph` 命令打印同一份已解析图。同一能力有多个 Provider 时，选择写在配置里，不靠注册顺序。

### 横切逻辑没有固定位置

认证、租户、授权、校验、幂等、事务分别散在过滤器、拦截器、基类虚方法里，顺序靠约定。这里它们落在管道的固定阶段，任何协议进来的调用都经过同一条管道。中间件只关心自己的阶段，顺序由「阶段、约束、归属」确定并可打印，不依赖动态代理。

### 一个业务三份胶水

要同时提供 REST、gRPC 与 MCP，通常得写控制器、proto 与 tool 描述三份东西，还要各自维护授权与错误码。这里操作以 `[Operation]` 声明一次，源生成器产出 JSON Schema。HTTP 路由、OpenAPI 文档、gRPC 的 `.proto`、MCP 的 tool 描述、命令行参数都由同一份契约推出，授权要求与错误码在各协议上一致。

### 开发环境离不开基础设施

很多框架的抽象没有能用的默认实现，本地跑起来要先装数据库、Redis 和消息代理。这里每个子系统的抽象都有一个零外部依赖、容量有界的默认实现。上线时加 Provider 包与一行 `UseFeature`，默认实现自动让位；Provider 与默认实现通过同一套一致性套件，行为差异在套件里可见。

### 架构约束靠人记

依赖方向、命名、分层这些规则写在文档里，靠代码评审记忆，三个月后就松了。这里依赖方向、包 ID 文法、命名空间、零反射、第三方类型泄漏、XML 文档、消息键与语言文件的一致性都由架构测试与分析器执行，违反即 CI 失败。

## 与同类框架的对比

下面三张表只列差异点，不评价优劣。它们各自解决的问题不同，适合的团队也不同。

### ABP Framework

| 维度 | ABP | XiHan |
| --- | --- | --- |
| 模块化 | 强制模块系统，`[DependsOn]` 加生命周期钩子 | 能力包是可选组织方式，`IFeature` 加 `UseFeature<T>()` 显式组合，依赖写在清单里按能力 ID 解析 |
| 实体基类 | 继承 `Entity<TKey>` 等基类 | 只提供接口协议（`IEntity<TKey>`、`ISoftDeletable`、`IMultiTenant`），按需组合 |
| 扩展机制 | 拦截器加虚方法重写 | 固定阶段的管道中间件加源生成器 |
| 动态代理 | 运行时代理 | 零反射，编译期生成 |
| 包数量 | 五十以上 | 内核两包（`Primitives`、`Kernel`）加按领域的子系统包，三个组合包收口 |
| 依赖注入 | 包装 MS DI 加自动注册 | 原生 MS DI 加显式注册，生成器登记可选入 |
| 对外暴露 | 动态 API（HTTP） | 操作契约，一份契约暴露为 HTTP、gRPC、MCP、命令行 |
| 跨语言 | 无 | 规范加一致性测试加各语言 SDK |

### Furion

| 维度 | Furion | XiHan |
| --- | --- | --- |
| 设计理念 | 大而全的全家桶，开箱即用 | 微内核加可选能力包，按需加载；默认实现保证开箱即用 |
| 依赖注入 | 属性扫描自动注册 | 显式注册加可选源生成器注册 |
| 动态 API | 内置核心功能 | 操作契约加 `Protocols.Http` 适配器 |
| 配置方式 | 约定为主，配置为辅 | 显式为主，约定可覆写，二者都有退出机制 |
| 包结构 | 单一主包加少量扩展 | 抽象包加按机制或技术命名的实现包 |
| 目标场景 | 中小型项目快速开发 | 中大型、长期维护、需要跨团队共识的项目 |

### MASA Framework

| 维度 | MASA | XiHan |
| --- | --- | --- |
| 设计理念 | 云原生、微服务优先 | 部署形态中立，应用清单一键产出容器与 Kubernetes 产物 |
| 模块化 | Building Blocks | 能力图谱加管道阶段 |
| 数据访问 | 多 ORM | `Persistence.Abstractions` 加 EF Core 与 SqlSugar 两个 Provider |
| 可观测性 | 集成 OpenTelemetry | 内核直接基于 `System.Diagnostics`，`Observability.OpenTelemetry` 只配导出器 |
| 多租户 | 内置 | `MultiTenancy.*` 子系统，管道 Tenant 阶段 |

## 换来的代价

| 代价 | 说明 |
| --- | --- |
| 写法更显式 | 每个特性要写清单；服务、权限、操作、消息处理器都要在 `Configure` 里显式登记，源生成器的登记也要显式调用 |
| 序列化要源生成 | 操作的请求与响应、领域事件的载荷要登记到 `JsonSerializerContext`；类型没有登记时生成器报 `XHG002` |
| 失败用 `Result` 表达 | 仓储、缓存、消息等端口返回 `Result` 而不是抛异常，调用方要处理失败分支 |
| 文案不写在代码里 | 面向人的文字以消息键引用，每个键要在十个语言文件里各有一行 |
| 概念更多 | 能力 ID、清单、管道阶段、操作契约、协议适配器是新概念，团队需要时间统一认识 |

我认为这些代价都是值得的，因为它们换来的是十年尺度上的可维护性。但如果你的项目生命周期只有几个月，这些约束就只是负担。

## 当前限制

- 当前只有预览版，安装要带 `--prerelease`，见[环境与安装](/getting-started/installation)。
- 公开面多数标为 `Preview` 或 `Experimental`，正式版前仍可能调整。
- 框架不提供机器人、消息通知渠道、模板引擎、脚本引擎、搜索引擎、HTTP 客户端封装、网关、SignalR 封装、对象映射，替代做法见[常见问题](/appendix/faq)。
- Provider 覆盖面以[包参考](/packages/)列出的为准：持久化有 EF Core 与 SqlSugar，没有 MongoDB；远程配置有 Nacos，没有 Apollo 与 Vault；对象存储有文件系统与 S3 兼容服务。

## 用最小成本验证

1. 按[第一个应用](/getting-started/first-app)写一个操作，确认装配、管道与 Problem Details 的行为。
2. 运行[示例](/appendix/samples)里的 `SimpleApp`：同一份订单契约同时在 HTTP、gRPC、MCP 上服务，带租户、认证、权限、事务与发件箱，零外部设施。
3. 把其中一个默认实现换成团队要用的 Provider，确认业务代码不需要改。

## 下一步

- [设计哲学](/appendix/philosophy)：这些取舍背后的原则
- [环境与安装](/getting-started/installation)：开始动手
