Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ dotnet test DesignPatterns.slnx -c Release
| Event Aggregator | `IEventAggregator`、`[RegisterEventHandler]` | `RegisterEventHandlerGenerator` |
| Command Router | `ICommandRouter`、`IStreamCommandHandler`、`[RegisterCommandHandler]` | `RegisterCommandHandlerGenerator` |
| State(M1–M2) | `ITransitionTable`、`[StateMachine]`、`[Transition]` | `StateTransitionGenerator` |
| Step Builder | `[GenerateBuilder]`、`[BuilderStep]`、`[BuilderAssemble]`、`BuilderStepState` | `GenerateBuilderGenerator` |
| DI Health Checks | `AddDesignPatternsHealthChecks`、`IHealthCheck` | —(运行时扩展) |

模式文档见 [docs/design/](docs/design/README.md)。横切约定见 [docs/FactoryKeyConventions.md](docs/FactoryKeyConventions.md)。架构决策见 [docs/adr/](docs/adr/README.md)。
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **Step Builder Design Doc + ADR-010**: `docs/design/StepBuilder.md` documents attributes, generated `{Holder}Builder` type-state proof model, DP078–DP086, non-goals, and explicit comparison vs registration/assembly `*Builder` types; [ADR-010](docs/adr/ADR-010-step-builder-type-state-markers.md) records generic type-state + required-step cap 8; design index, ROADMAP F3 Top-2, and AGENTS pattern summary updated ([#291](https://github.com/Skymly/DesignPatterns/issues/291), Spec [#287](https://github.com/Skymly/DesignPatterns/issues/287)).
- **Step Builder generator**: `[GenerateBuilder]` drives `GenerateBuilderGenerator`, emitting `{Holder}Builder` with generic type-state markers for required steps, at-most-once step methods, and gated `Build()` that invokes `[BuilderAssemble]` with name-bound arguments (optional unset → null). Reports **DP078–DP086** for schema/contract errors; sync-only MVP with no DI/Autofac emission ([#290](https://github.com/Skymly/DesignPatterns/issues/290)).
- **Step Builder diagnostic IDs**: reserved **DP078–DP086** for the upcoming `[GenerateBuilder]` generator (required-step cap, missing assemble, assemble parameter mismatch, mutex conflict, partial-order violation, duplicate step, unknown After/Before reference, invalid holder, assemble contract mismatch); DP067–DP071 remain ADR-008-only ([#289](https://github.com/Skymly/DesignPatterns/issues/289)).
- **Command Router stream Design Doc**: `docs/design/CommandRouter.md` documents `IStreamCommandHandler` / `SendStreamAsync` / `TrySendStreamAsync`, failure modes, void/result/stream 1:1 bijection, generator reuse of `[RegisterCommandHandler]`, and explicit non-goals (no stream pipeline, no separate Stream Request Router domain); MediatR comparison and ROADMAP F3 updated ([#283](https://github.com/Skymly/DesignPatterns/issues/283)).
Expand Down
3 changes: 2 additions & 1 deletion docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
| Event Aggregator | `{Event}EventHandlerRegistry` |
| Command Router | `{Command}CommandHandlerRegistry` |
| State | `{StateEnum}TransitionTable`、partial `{Holder}` 便捷方法 |
| Step Builder | `{Holder}Builder` / `{Holder}Builder<…>`(type-state) |

新增生成器必须沿用此命名风格(详见 [Decorator.md](design/Decorator.md))。诊断 ID 续接现有区段,下一个可用 ID 为 **DP087**(DP078–DP086 为 Step Builder / GenerateBuilder:必填步上限、缺装配、参数绑定、互斥、偏序、重复步骤、未知步骤引用、非法 holder、装配契约;DP075–DP077 为 Command Router pipeline behaviors:重复 order、孤儿 behavior、契约不匹配;DP072–DP074 为 Command Router:未注册 Analyzer、重复命令、契约不匹配;DP067–DP071 专属 [ADR-008](adr/ADR-008-singleton-lifecycle-diagnostics.md) Singleton 生命周期语义,不得改派;DP066 为 Singleton 工厂委托 captive dependency,DP063–DP065 为 Composite 树 schema 校验,DP060–DP062 为 DI 生命周期校验,DP056–DP059 为 State hierarchy,DP053–DP055 为 Factory async + pooling 签名/池化校验,DP050–DP052 为 Handler guard 签名校验,DP047–DP049 为 Strategy guard 签名校验,DP044–DP046 为 EventAggregator 源生成器 + Analyzer 诊断,DP042–DP043 为 Decorator DI + async 签名校验,DP040–DP041 为 Composite DI + visitor 覆盖校验,DP037–DP039 为 State entry/exit action 诊断,DP032–DP035 为 State guard 诊断,DP036 为 State 字面量边校验;ID 一经发布不复用,详见 [AGENTS.md](../AGENTS.md))。

Expand Down Expand Up @@ -105,7 +106,7 @@
| 名次 | 候选 | 说明 | 状态 |
|------|------|------|------|
| 1 | **Command Router** | MVP + 域内增强已落地:1:1 `SendAsync`/`TrySendAsync`/`SendStreamAsync`/`TrySendStreamAsync` + `[RegisterCommandHandler]`(含 `IStreamCommandHandler`)+ DP072–077 + pipeline(ADR-009)+ `AddCommandRouter` / Autofac `RegisterCommandRouter` + [Design Doc](design/CommandRouter.md)(#257–#265、#275–#277、#282–#283)。Samples #266;探索与 MediatR 的差异点见 Design Doc | [~] |
| 2 | **Builder** | 声明式步骤 → 生成 fluent `*Builder`;缺步 / 不完整 `Build` 的编译期证明与诊断 | [ ] |
| 2 | **Builder**(Step Builder) | MVP 已落地:`[GenerateBuilder]` / `[BuilderStep]` / `[BuilderAssemble]` + 泛型 type-state `{Holder}Builder`([ADR-010](adr/ADR-010-step-builder-type-state-markers.md))+ DP078–DP086 + [Design Doc](design/StepBuilder.md)(#288–#291)。Samples 待 sibling;async / DI 为 Phase 2+ | [~] |
| 3 | **Fork–Join Work Graph** | 属性声明的工作 DAG;生成器校验环 / 孤儿依赖并生成拓扑波次编排 | [ ] |

#### 观望(已过硬门槛,未进 Top-3)
Expand Down
39 changes: 39 additions & 0 deletions docs/adr/ADR-010-step-builder-type-state-markers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ADR-010: Step Builder required completeness via generic type-state markers

| 字段 | 值 |
|------|-----|
| **状态** | Accepted |
| **日期** | 2026-08-03 |
| **关联 Issue** | [#287](https://github.com/Skymly/DesignPatterns/issues/287)(Spec)、[#288](https://github.com/Skymly/DesignPatterns/issues/288)–[#291](https://github.com/Skymly/DesignPatterns/issues/291) |

## 背景

F3 Top-2 **Builder / Step Builder** 需要在编译期证明「所有必填步骤已应用」后才可调用 `Build()`。可选编码包括:每子集一个接口的阶段图、Analyzer 事后校验调用链、或带 phantom 类型参数的泛型 type-state。须同时限制必填步数量,避免标记组合爆炸,并与注册/装配用的 `*Builder`(如 `FactoryRegistryBuilder`)划清语义边界。

## 决策

Step Builder 的必填完整性**只采用泛型 type-state 标记**,并遵守下列配套约束:

1. **编码**:生成 `{Holder}Builder<…>`,每个**必填**步骤对应一个类型参数,在 `BuilderStepState.NotSet` ↔ `BuilderStepState.Set` 间翻转;仅当全部必填参数均为 `Set` 时暴露可调用的 `Build()`。
2. **上限**:每个 holder 至多 **8** 个必填 `[BuilderStep]`;超出报 **DP078**。可选步骤**不**占用 type 参数,也**不**计入该上限。
3. **非默认路径**:不以「interface-per-subset」阶段图为默认编码;不以 Analyzer 作为必填完整性的**主**门闩(可日后叠加,但不替代 type-state)。
4. **可选 / 互斥 / 偏序**:不进 type-state;schema 级由生成器诊断(DP081–DP082、DP084 等)约束,非法应用顺序在生成的 fluent 方法中以运行时 `InvalidOperationException` 拒绝。
5. **装配**:产品由用户 `[BuilderAssemble]` 方法物化;生成器不发明对象映射。产品类型 = assemble 返回类型。
6. **MVP 非目标**:async `Build`/assemble、MSDI/Autofac、`FromServices` 步进注入、Core 内手写 type-state 孪生、Director 厚基类体系。

## 后果

**正面**:
- 缺必填步时 `Build()` 在调用方编译失败,无需运行时发现
- 标记类型集中在 `BuilderStepState`,生成器与消费方可共享同一 phantom 约定
- 与注册 `*Builder` 的「装配注册表」语义明确分离

**负面**:
- 必填步上限 8 限制超大 schema(有意;可拆 holder 或将多余步标为可选)
- 互斥 / 偏序在 MVP 不以 type-state 擦除,依赖诊断 + 运行时拒绝,调用链上仍可能写出后在运行时报错的非法序列

## 参考

- [docs/design/StepBuilder.md](../design/StepBuilder.md)
- Spec [#287](https://github.com/Skymly/DesignPatterns/issues/287)
- 落地切片:#288(Runtime)→ #289(Diagnostics)→ #290(SourceGenerators)→ #291(Docs)
3 changes: 2 additions & 1 deletion docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
| [ADR-007](ADR-007-composite-tree-schema-validation.md) | Composite tree schema validation | Accepted | 2026-07-07 | — |
| [ADR-008](ADR-008-singleton-lifecycle-diagnostics.md) | Singleton lifecycle diagnostics | Accepted | 2026-07-08 | — |
| [ADR-009](ADR-009-command-router-pipeline-onion.md) | Command Router pipeline uses Chain-like next onion | Accepted | 2026-07-28 | #264 / #275–#277 |
| [ADR-010](ADR-010-step-builder-type-state-markers.md) | Step Builder required completeness via generic type-state markers | Accepted | 2026-08-03 | #287 / #288–#291 |

## 下一个可用编号

**ADR-010**
**ADR-011**
1 change: 1 addition & 0 deletions docs/design/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
| Event Aggregator | [EventAggregator.md](EventAggregator.md) | — |
| Command Router | [CommandRouter.md](CommandRouter.md) | — |
| State Transition Table | [StateTransitionTable.md](StateTransitionTable.md) | [ADR-005](../adr/ADR-005-state-transition-table.md) |
| Step Builder | [StepBuilder.md](StepBuilder.md) | [ADR-010](../adr/ADR-010-step-builder-type-state-markers.md) |
Loading
Loading