diff --git a/AGENTS.md b/AGENTS.md index 1e57ac2..88665c3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,7 @@ | **远端** | https://github.com/Skymly/DesignPatterns(**公开**);文件夹名 `DesignPatterns` = 仓库名 | | **许可证** | [MIT](LICENSE) | | **阶段** | **早期预览**:公共 API、生成器产出与 `DP###` 诊断**尚未稳定**(见 [README.md](README.md)) | -| **NuGet** | 元包 **`Skymly.DesignPatterns`**;当前 **`0.2.2`**;`release.yml` + Nuke `Publish` → nuget.org + GitHub Packages | +| **NuGet** | 元包 **`Skymly.DesignPatterns`**;当前 **`0.2.3-preview1`**;`release.yml` + Nuke `Publish` → nuget.org + GitHub Packages | | **Sibling 仓库** | [DesignPatterns.Samples](https://github.com/Skymly/DesignPatterns.Samples)、[DesignPatterns.Docs](https://github.com/Skymly/DesignPatterns.Docs) — 工作区路径 `Skymly/DesignPatterns/DesignPatterns.Samples/`、`Skymly/DesignPatterns/DesignPatterns.Docs/` | ## 项目是什么 @@ -258,7 +258,7 @@ git push origin v0.1.0-preview3 版本与变更记录: -- 版本号:`VersionPrefix` + `VersionSuffix`(当前 `0.2.2`),单一真相源为 [`Directory.Build.props`](Directory.Build.props);发版时可通过环境变量 `VERSION` 覆盖。 +- 版本号:`VersionPrefix` + `VersionSuffix`(当前 `0.2.3-preview1`),单一真相源为 [`Directory.Build.props`](Directory.Build.props);发版时可通过环境变量 `VERSION` 覆盖。 - 变更记录:[`CHANGELOG.md`](CHANGELOG.md)(Keep a Changelog 风格)。 --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c50996..f5a10d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,17 +9,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.3-preview1] - 2026-07-18 + ### Added -- **Composite parallel traversal**: `CompositeTraverser.TraverseParallel` / `TraverseParallelAsync` / `TraverseForestParallel` / `TraverseForestParallelAsync` — parallel tree traversal with `MaxDegreeOfParallelism` and `MaxParallelDepth` options. BFS same-level parallel, DFS child-parallel recursion with sequential fallback beyond depth threshold. `AggregateException` for error aggregation. `ConfigureAwait(false)` for async paths. `#if` split: `Parallel.ForEachAsync` on net8.0, `SemaphoreSlim` + `Task.WhenAll` on netstandard2.0. 17 new tests. See [ADR-006](docs/adr/ADR-006-composite-parallel-traversal.md). -- **DP062 Phase 2 — generated RegisterDi coverage**: `CaptiveDependencyAnalyzer` now also scans `RegisterDi` calls from DesignPatterns source generators. Extracts `implementationLifetime` (or `lifetime` for single-param overloads) and applies it to all types bearing `[RegisterStrategy]`, `[RegisterFactory]`, `[RegisterEventHandler]`, `[Decorator]`, `[CompositePart]` attributes. 5 new Verify snapshot tests. -- **Singleton lifecycle diagnostics P1 — Autofac and factory delegate coverage**: `CaptiveDependencyAnalyzer` now collects Autofac registrations (`RegisterType` + fluent lifetime chain, `Register(c => ...)`) via symbol-name matching with no Autofac package reference, and reports the new **DP066** (Warning) when a Singleton factory delegate (`AddSingleton(sp => ...)` or Autofac `Register(...).SingleInstance()`) directly resolves a Scoped/Transient service via `GetRequiredService`/`GetService`/`Resolve`. MSDI factory and instance registrations now also feed the lifetime map, so Singletons constructor-depending on factory-registered Scoped/Transient services report DP062. Limitation: only direct resolution calls inside the delegate body are detected. 11 new Verify snapshot tests. See [ADR-008](docs/adr/ADR-008-singleton-lifecycle-diagnostics.md). -- **Documentation system simplification**: Removed in-repo RFC / Spec / Plan / Review document types. Spec content merged into Design Docs; task tracking and review use GitHub Issues / PRs. See [docs/DOCUMENTATION.md](docs/DOCUMENTATION.md). +- **Async Singleton initialization**: `[GenerateSingleton(InitializeAsync = nameof(Method))]` validates static `Task`/`ValueTask` initializers and generates `GetInstanceAsync()` backed by a lazy async singleton. Invalid initializer signatures report **DP067**. +- **Singleton lifecycle diagnostics**: added **DP068** for generated Singleton plus DI double registration, **DP069** for mutable state on non-thread-safe generated Singletons, **DP070** for mutable static Singleton candidates, and **DP071** for mutable static Singleton plus DI registration. +- **Diagnostic and integration coverage**: added generator, analyzer, runtime integration, package, and CI verification for the new Singleton lifecycle behavior. ## [0.2.2] - 2026-06-30 ### Added +- **Composite parallel traversal**: `CompositeTraverser.TraverseParallel` / `TraverseParallelAsync` / `TraverseForestParallel` / `TraverseForestParallelAsync` — parallel tree traversal with `MaxDegreeOfParallelism` and `MaxParallelDepth` options. BFS same-level parallel, DFS child-parallel recursion with sequential fallback beyond depth threshold. `AggregateException` for error aggregation. `ConfigureAwait(false)` for async paths. `#if` split: `Parallel.ForEachAsync` on net8.0, `SemaphoreSlim` + `Task.WhenAll` on netstandard2.0. 17 new tests. See [ADR-006](docs/adr/ADR-006-composite-parallel-traversal.md). +- **DP062 Phase 2 — generated RegisterDi coverage**: `CaptiveDependencyAnalyzer` now also scans `RegisterDi` calls from DesignPatterns source generators. Extracts `implementationLifetime` (or `lifetime` for single-param overloads) and applies it to all types bearing `[RegisterStrategy]`, `[RegisterFactory]`, `[RegisterEventHandler]`, `[Decorator]`, `[CompositePart]` attributes. 5 new Verify snapshot tests. +- **Singleton lifecycle diagnostics P1 — Autofac and factory delegate coverage**: `CaptiveDependencyAnalyzer` now collects Autofac registrations (`RegisterType` + fluent lifetime chain, `Register(c => ...)`) via symbol-name matching with no Autofac package reference, and reports the new **DP066** (Warning) when a Singleton factory delegate (`AddSingleton(sp => ...)` or Autofac `Register(...).SingleInstance()`) directly resolves a Scoped/Transient service via `GetRequiredService`/`GetService`/`Resolve`. MSDI factory and instance registrations now also feed the lifetime map, so Singletons constructor-depending on factory-registered Scoped/Transient services report DP062. Limitation: only direct resolution calls inside the delegate body are detected. 11 new Verify snapshot tests. See [ADR-008](docs/adr/ADR-008-singleton-lifecycle-diagnostics.md). +- **Documentation system simplification**: Removed in-repo RFC / Spec / Plan / Review document types. Spec content merged into Design Docs; task tracking and review use GitHub Issues / PRs. See [docs/DOCUMENTATION.md](docs/DOCUMENTATION.md). + - **Singleton captive dependency diagnostic (DP062)**: `CaptiveDependencyAnalyzer` reports DP062 (Warning) when a Singleton service's constructor depends on a Scoped or Transient service. Scans `AddSingleton`/`AddScoped`/`AddTransient`/`TryAdd(ServiceDescriptor)` calls to build a type-to-lifetime registration map, then checks each Singleton implementation's constructor parameters against the map. 11 Verify snapshot tests. ### Previous preview (0.2.1-preview1) @@ -124,6 +130,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `WithTrackingName` to generator pipelines and added cache-hit regression tests. - Migrated analyzer tests to Verify snapshots for consistency with generator tests. +[0.2.3-preview1]: https://github.com/Skymly/DesignPatterns/releases/tag/v0.2.3-preview1 [0.2.0-preview1]: https://github.com/Skymly/DesignPatterns/releases/tag/v0.2.0-preview1 [0.1.0-preview7]: https://github.com/Skymly/DesignPatterns/releases/tag/v0.1.0-preview7 diff --git a/DesignPatterns.Analyzers/AnalyzerReleases.Shipped.md b/DesignPatterns.Analyzers/AnalyzerReleases.Shipped.md index 7207290..79ae5d7 100644 --- a/DesignPatterns.Analyzers/AnalyzerReleases.Shipped.md +++ b/DesignPatterns.Analyzers/AnalyzerReleases.Shipped.md @@ -14,3 +14,15 @@ DP044 | DesignPatterns.Analyzers | Info | Event handler implementation mi DP060 | DesignPatterns.Analyzers | Warning | DI captive dependency: registry lifetime exceeds implementation lifetime DP061 | DesignPatterns.Analyzers | Info | DI lifetime mismatch: implementation lifetime exceeds registry lifetime DP062 | DesignPatterns.Analyzers | Warning | Singleton captive dependency on Scoped/Transient service +DP066 | DesignPatterns.Analyzers | Warning | Singleton factory delegate captures shorter-lived service + +## Release 0.2.3 + +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +DP068 | DesignPatterns.Analyzers | Warning | Generated singleton is also registered with DI +DP069 | DesignPatterns.Analyzers | Info | Non-thread-safe singleton has mutable instance state +DP070 | DesignPatterns.Analyzers | Info | Static mutable singleton candidate +DP071 | DesignPatterns.Analyzers | Warning | Static mutable singleton is also registered with DI diff --git a/DesignPatterns.Analyzers/AnalyzerReleases.Unshipped.md b/DesignPatterns.Analyzers/AnalyzerReleases.Unshipped.md index fa74702..c903787 100644 --- a/DesignPatterns.Analyzers/AnalyzerReleases.Unshipped.md +++ b/DesignPatterns.Analyzers/AnalyzerReleases.Unshipped.md @@ -2,8 +2,3 @@ Rule ID | Category | Severity | Notes --------|----------|----------|------- -DP066 | DesignPatterns.Analyzers | Warning | Singleton factory delegate captures shorter-lived service -DP068 | DesignPatterns.Analyzers | Warning | Generated singleton is also registered with DI -DP069 | DesignPatterns.Analyzers | Info | Non-thread-safe singleton has mutable instance state -DP070 | DesignPatterns.Analyzers | Info | Static mutable singleton candidate -DP071 | DesignPatterns.Analyzers | Warning | Static mutable singleton is also registered with DI diff --git a/Directory.Build.props b/Directory.Build.props index 505d3d6..1d657dc 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,9 +6,9 @@ true - 0.2.2 - - $(VersionPrefix) + 0.2.3 + preview1 + $(VersionPrefix)-$(VersionSuffix) $(Version) Skymly diff --git a/README.md b/README.md index 39d539c..887cde9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ > **本仓库已开源([MIT](LICENSE)),但处于早期开发阶段。** > > - **公共 API 尚未稳定**:类型、特性、源生成器产出、诊断 ID(`DP###`)及命名规则可能在任意版本变更,**不保证**语义化版本下的向后兼容。 -> - **NuGet 发布**:元包 **`Skymly.DesignPatterns`** **`0.2.2`** 发布至 [nuget.org](https://www.nuget.org/packages/Skymly.DesignPatterns) 与 GitHub Packages;亦支持本地 `./build.ps1 --target CiPack`。C# 命名空间仍为 `DesignPatterns.*`;旧 GitHub 包 ID `DesignPatterns`(preview1/2)已弃用。 +> - **NuGet 发布**:元包 **`Skymly.DesignPatterns`** **`0.2.3-preview1`** 发布至 [nuget.org](https://www.nuget.org/packages/Skymly.DesignPatterns) 与 GitHub Packages;亦支持本地 `./build.ps1 --target CiPack`。C# 命名空间仍为 `DesignPatterns.*`;旧 GitHub 包 ID `DesignPatterns`(preview1/2)已弃用。 > - **生产环境**:建议仅在可接受 API 变动的实验、内部工具或学习场景使用;在 API 稳定前请固定 commit 或 fork,并关注 [ROADMAP](docs/ROADMAP.md) 与 breaking changes。 **English:** This project is open source under the MIT license and in an **early preview**. Public APIs, generated code shapes, and diagnostics are **not stable** yet. Do not assume SemVer compatibility until a stability announcement. @@ -96,10 +96,10 @@ DesignPatterns.slnx ## 快速开始 -### NuGet(`Skymly.DesignPatterns` `0.2.2`) +### NuGet(`Skymly.DesignPatterns` `0.2.3-preview1`) ```xml - + ``` 默认从 [nuget.org](https://api.nuget.org/v3/index.json) 还原。GitHub Packages 镜像(可选): diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 10fe97e..e9e8271 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -110,7 +110,7 @@ | Decorator 组合 / 嵌套 | `DecoratorStackBuilder.Compose(otherStack)`,Analyzer 校验栈间类型兼容 | ⭐⭐ 可复用装饰器组合 | | MSDI keyed services(.NET 8+) | 生成 keyed registration 代码(`#if NET8_0_OR_GREATER`),与 Autofac keyed 对称 | ⭐⭐ 补齐 MSDI keyed 缺口 | | DI 健康检查 + 生命周期校验 | 生成 `IHealthCheck` 校验注册表键可解析;Analyzer 警告无效 lifetime 组合(Singleton registry + Transient impl) | ⭐⭐ 生产场景刚需 | -| Singleton 生命周期诊断 | Analyzer 检测 singleton 捕获 scoped/transient 引用;async 初始化支持。[~] P1 已完成(DP066);P2/P3 见 [ADR-008](adr/ADR-008-singleton-lifecycle-diagnostics.md) | ⭐⭐ 防 DI 反模式 | +| Singleton 生命周期诊断 | Analyzer 检测 singleton 捕获 scoped/transient 引用;async 初始化支持。P1–P3 已完成(DP066–DP071),见 [ADR-008](adr/ADR-008-singleton-lifecycle-diagnostics.md) | ⭐⭐ 防 DI 反模式 | State 转换表 v1 已于 0.1.0-preview4 发布;v2(guard 委托、DI 集成、DP036 字面量边校验)已实现,见 [StateTransitionTable.md](design/StateTransitionTable.md)。EventAggregator 联动示例仍为候选。 @@ -138,7 +138,7 @@ State 转换表 v1 已于 0.1.0-preview4 发布;v2(guard 委托、DI 集成 - **API 冻结**:公共类型 / 特性 / 生成产出 / `DP###` 命名稳定声明(先行条件)。 - **打包修复**:元包多目标(`lib/net8.0`)已完成;「DI 扩展打包归属」仍待确定。 -- **NuGet 首发 / SemVer**:`Skymly.DesignPatterns` `0.2.2`(`Directory.Build.props` + `release.yml`);稳定版待 API 冻结。 +- **NuGet 首发 / SemVer**:`Skymly.DesignPatterns` `0.2.3-preview1`(`Directory.Build.props` + `release.yml`);稳定版待 API 冻结。 - ~~**release.yml**~~:tag 触发 Publish — 已完成。 开关条件:F1/F2/F2+ 主要项落地且无未决破坏性设计时,再评估进入本支线。 diff --git a/docs/design/ChainOfResponsibility.md b/docs/design/ChainOfResponsibility.md index 75d04bc..bb65aca 100644 --- a/docs/design/ChainOfResponsibility.md +++ b/docs/design/ChainOfResponsibility.md @@ -1,6 +1,6 @@ # Design Doc: Chain of Responsibility -> **版本**:v0.2.2(与 NuGet 包版本对齐) +> **版本**:v0.2.3-preview1(与 NuGet 包版本对齐) > **关联 ADR**:ADR-XXX(如有) ## 概述 diff --git a/docs/design/Composite.md b/docs/design/Composite.md index 85c39c2..07b2c0a 100644 --- a/docs/design/Composite.md +++ b/docs/design/Composite.md @@ -1,6 +1,6 @@ # Design Doc: Composite -> **版本**:v0.2.2(与 NuGet 包版本对齐) +> **版本**:v0.2.3-preview1(与 NuGet 包版本对齐) > **关联 ADR**:[ADR-006](../adr/ADR-006-composite-parallel-traversal.md)、[ADR-007](../adr/ADR-007-composite-tree-schema-validation.md) ## 概述 diff --git a/docs/design/Decorator.md b/docs/design/Decorator.md index e9b1d5f..fcb7bca 100644 --- a/docs/design/Decorator.md +++ b/docs/design/Decorator.md @@ -1,6 +1,6 @@ # Design Doc: Decorator -> **版本**:v0.2.2(与 NuGet 包版本对齐) +> **版本**:v0.2.3-preview1(与 NuGet 包版本对齐) > **关联 ADR**:ADR-XXX(如有) ## 概述 diff --git a/docs/design/EventAggregator.md b/docs/design/EventAggregator.md index 8920898..34dfcaf 100644 --- a/docs/design/EventAggregator.md +++ b/docs/design/EventAggregator.md @@ -1,6 +1,6 @@ # Design Doc: Event Aggregator -> **版本**:v0.2.2 +> **版本**:v0.2.3-preview1 > **关联 ADR**:ADR-XXX(如有) ## 概述 diff --git a/docs/design/FactoryRegistry.md b/docs/design/FactoryRegistry.md index aa2a8c7..48264b0 100644 --- a/docs/design/FactoryRegistry.md +++ b/docs/design/FactoryRegistry.md @@ -1,6 +1,6 @@ # Design Doc: Factory Registry -> **版本**:v0.2.2(与 NuGet 包版本对齐) +> **版本**:v0.2.3-preview1(与 NuGet 包版本对齐) > **关联 ADR**:ADR-XXX(如有) ## 概述 diff --git a/docs/design/StateTransitionTable.md b/docs/design/StateTransitionTable.md index b142e32..2a9b337 100644 --- a/docs/design/StateTransitionTable.md +++ b/docs/design/StateTransitionTable.md @@ -1,6 +1,6 @@ # Design Doc: State 转换表 -> **版本**:v0.2.2(与 NuGet 包版本对齐) +> **版本**:v0.2.3-preview1(与 NuGet 包版本对齐) > **关联 ADR**:[ADR-005](../adr/ADR-005-state-transition-table.md) ## 概述 diff --git a/docs/design/Strategy.md b/docs/design/Strategy.md index 90a0167..804c72f 100644 --- a/docs/design/Strategy.md +++ b/docs/design/Strategy.md @@ -1,6 +1,6 @@ # Design Doc: Strategy -> **版本**:v0.2.2(与 NuGet 包版本对齐) +> **版本**:v0.2.3-preview1(与 NuGet 包版本对齐) ## 概述