Skip to content

feat(state): 添加运行时临时注册与注销功能#133

Merged
GeWuYou merged 3 commits into
mainfrom
feat/state-dynamic-registration
Mar 23, 2026
Merged

feat(state): 添加运行时临时注册与注销功能#133
GeWuYou merged 3 commits into
mainfrom
feat/state-dynamic-registration

Conversation

@GeWuYou
Copy link
Copy Markdown
Owner

@GeWuYou GeWuYou commented Mar 23, 2026

  • 实现 RegisterReducerHandle 和 RegisterMiddleware 方法,支持获取注销句柄
  • 添加 IUnRegister 接口和 DefaultUnRegister 实现,提供精确注销能力
  • 修改内部数据结构,使用 Registration 包装对象确保注销时的身份稳定性
  • 实现中间件和 reducer 的快照机制,确保运行中注销不影响当前 dispatch
  • 添加相关单元测试验证运行时注册注销的正确性
  • 更新文档说明运行时临时注册与注销的使用方式和约束条件

Summary by Sourcery

为 store 中的 reducers 和 middlewares 添加基于运行时句柄的注册机制和精确注销支持,同时保持 dispatch 快照语义不变。

New Features:

  • 引入基于句柄的 API,用于注册 reducers 和 middlewares,并返回注销句柄,以支持精确的运行时清理。

Enhancements:

  • 将内部 middleware 和 reducer 的注册封装在专用的注册对象中,在不改变执行顺序的前提下提供稳定的标识。
  • 优化 middleware 和 reducer 快照的创建逻辑,使其适配新的注册封装,同时保持 dispatch 行为稳定。
  • 重组 store 的诊断属性,但不改变其对外可见的行为。

Documentation:

  • 记录运行时临时注册与注销的工作流程,包括使用示例,以及对 reducers 和 middlewares 的行为约束说明。

Tests:

  • 添加单元测试,覆盖基于句柄的注册/注销、部分移除后的顺序保持、幂等注销,以及在进行中的 dispatch 过程中注销等场景。
Original summary in English

Summary by Sourcery

Add runtime handle-based registration and precise unregistration support for reducers and middlewares in the store while preserving dispatch snapshot semantics.

New Features:

  • Introduce handle-based APIs for registering reducers and middlewares that return unregistration handles for precise runtime cleanup.

Enhancements:

  • Wrap internal middleware and reducer registrations in dedicated registration objects to provide stable identities without changing execution order.
  • Refine middleware and reducer snapshot creation to work with the new registration wrappers while keeping dispatch behavior stable.
  • Reorganize store diagnostic properties without changing their public behavior.

Documentation:

  • Document the runtime temporary registration and unregistration workflow, including usage examples and behavioral constraints for reducers and middlewares.

Tests:

  • Add unit tests covering handle-based registration/unregistration, order preservation after partial removal, idempotent unregistration, and unregistering during an in-flight dispatch.

- 实现 RegisterReducerHandle 和 RegisterMiddleware 方法,支持获取注销句柄
- 添加 IUnRegister 接口和 DefaultUnRegister 实现,提供精确注销能力
- 修改内部数据结构,使用 Registration 包装对象确保注销时的身份稳定性
- 实现中间件和 reducer 的快照机制,确保运行中注销不影响当前 dispatch
- 添加相关单元测试验证运行时注册注销的正确性
- 更新文档说明运行时临时注册与注销的使用方式和约束条件
@deepsource-io
Copy link
Copy Markdown

deepsource-io Bot commented Mar 23, 2026

DeepSource Code Review

We reviewed changes in b6ef627...1f1aff5 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
C# Mar 23, 2026 12:58p.m. Review ↗
Secrets Mar 23, 2026 12:58p.m. Review ↗

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Mar 23, 2026

🧙 Sourcery 已完成对你的 Pull Request 的代码审查!


提示和命令

与 Sourcery 互动

  • 触发一次新的审查: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 通过回复某条审查评论,请求 Sourcery 从该评论创建一个 issue。你也可以回复审查评论 @sourcery-ai issue 来从该评论创建一个 issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题的任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 Pull Request 中评论 @sourcery-ai title 来随时(重新)生成标题。
  • 生成 Pull Request 概要: 在 Pull Request 正文的任意位置写上 @sourcery-ai summary,即可在你想要的位置生成 PR 概要。你也可以在 Pull Request 中评论 @sourcery-ai summary 来随时(重新)生成概要。
  • 生成审查者指南: 在 Pull Request 中评论 @sourcery-ai guide,即可随时(重新)生成审查者指南。
  • 解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,即可将所有 Sourcery 评论标记为已解决。如果你已经处理了所有评论且不想再看到它们,这会很有用。
  • 撤销所有 Sourcery 审查: 在 Pull Request 中评论 @sourcery-ai dismiss,即可撤销所有现有的 Sourcery 审查。如果你希望从一次全新的审查开始,这尤其有用 —— 别忘了再评论 @sourcery-ai review 来触发新的审查!

自定义你的体验

前往你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的 Pull Request 概要、审查者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查指令。
  • 调整其他审查设置。

获取帮助

Original review guide in English

🧙 Sourcery has finished reviewing your pull request!


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="GFramework.Core/StateManagement/Store.cs" line_range="623-632" />
<code_context>
+    ///     Dispatch 在离开状态锁前复制列表,以便后续在锁外执行稳定、不可变的中间件序列。
+    /// </summary>
+    /// <returns>当前中间件链的快照;若未注册则返回空数组。</returns>
+    private IStoreMiddleware<TState>[] CreateMiddlewareSnapshot()
+    {
+        if (_middlewares.Count == 0)
+        {
+            return Array.Empty<IStoreMiddleware<TState>>();
+        }
+
+        var snapshot = new IStoreMiddleware<TState>[_middlewares.Count];
+        for (var i = 0; i < _middlewares.Count; i++)
+        {
+            snapshot[i] = _middlewares[i].Middleware;
+        }
+
+        return snapshot;
+    }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** CreateMiddlewareSnapshot 假定由外部负责加锁,如果将来在其他地方复用,这可能会比较脆弱。

CreateMiddlewareSnapshot 在未取得 _lock 的情况下读取 _middlewares,目前只在 Dispatch 的临界区内被调用,所以现在是安全的,但这依赖于一个不明显的前置条件。如果有一天在锁外被调用,就可能引入竞争条件/一致性问题。

为了让它更安全、更清晰,可以选择在 CreateMiddlewareSnapshot 内部获取 _lock,或者传入一个已在锁保护下的 List<MiddlewareRegistration> 让它只做映射投影,或者把它做成一个明确“仅在加锁条件下使用”的辅助方法(例如带注释的本地函数)。这样可以降低未来重构时被误用的风险。
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请对每条评论点 👍 或 👎,我会根据这些反馈改进后续的评审。
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="GFramework.Core/StateManagement/Store.cs" line_range="623-632" />
<code_context>
+    ///     Dispatch 在离开状态锁前复制列表,以便后续在锁外执行稳定、不可变的中间件序列。
+    /// </summary>
+    /// <returns>当前中间件链的快照;若未注册则返回空数组。</returns>
+    private IStoreMiddleware<TState>[] CreateMiddlewareSnapshot()
+    {
+        if (_middlewares.Count == 0)
+        {
+            return Array.Empty<IStoreMiddleware<TState>>();
+        }
+
+        var snapshot = new IStoreMiddleware<TState>[_middlewares.Count];
+        for (var i = 0; i < _middlewares.Count; i++)
+        {
+            snapshot[i] = _middlewares[i].Middleware;
+        }
+
+        return snapshot;
+    }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** CreateMiddlewareSnapshot assumes external locking, which could be fragile if reused elsewhere.

CreateMiddlewareSnapshot reads _middlewares without taking _lock and is currently only used from within Dispatch’s critical section, so it’s safe today but relies on a non-obvious precondition. If it’s ever called outside the lock, it could introduce a race/consistency bug.

To make this safer and clearer, either acquire _lock inside CreateMiddlewareSnapshot, pass a locked List<MiddlewareRegistration> into it so it only projects, or make it a clearly "locked-only" helper (e.g., a local function) with a comment. This will reduce the risk of misuse in future refactors.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread GFramework.Core/StateManagement/Store.cs Outdated
GeWuYou added 2 commits March 23, 2026 20:41
- 添加GFramework.Core.Abstractions.Property命名空间引用
- 重新排序using语句以优化代码结构
- 保持现有功能不变的同时改进代码组织方式
- 为CreateMiddlewareSnapshot方法添加状态锁保护
- 为CreateReducerSnapshot方法添加状态锁保护
- 更新方法注释说明锁的安全性保障机制
- 避免调用方需要了解锁顺序的隐式依赖关系
@GeWuYou GeWuYou merged commit b912e6a into main Mar 23, 2026
9 checks passed
@GeWuYou GeWuYou deleted the feat/state-dynamic-registration branch March 23, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant