GFramework/GFramework.Core/Query/QueryExecutor.cs
gewuyou 6056159866 fix(core): 收口 legacy cqrs bridge 评审问题
- 修复 legacy bridge 测试装配与清理流程,改用 InternalsVisibleTo 和显式 handler 注册,补齐共享计数器重置与生命周期说明

- 优化 CommandExecutor、QueryExecutor 与相关模块的 runtime 契约,补充 XML 文档、nullable 注解和显式依赖解析

- 更新 legacy 异步 bridge 的取消语义、兼容文档回退边界以及 cqrs-rewrite active tracking/trace
2026-05-07 17:54:05 +08:00

84 lines
2.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
using System.Diagnostics.CodeAnalysis;
using GFramework.Core.Abstractions.Query;
using GFramework.Core.Abstractions.Rule;
using GFramework.Core.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Core.Query;
/// <summary>
/// QueryExecutor 类负责执行查询操作,实现 IQueryExecutor 接口。
/// 该类是密封的,防止被继承。
/// </summary>
public sealed class QueryExecutor(ICqrsRuntime? runtime = null) : IQueryExecutor
{
private readonly ICqrsRuntime? _runtime = runtime;
/// <summary>
/// 获取当前执行器是否已接入统一 CQRS runtime。
/// </summary>
public bool UsesCqrsRuntime => _runtime is not null;
/// <summary>
/// 执行指定的查询并返回结果。
/// 当查询对象携带可用的架构上下文且执行器已接入统一 runtime 时,
/// 该方法会先把 legacy 查询包装成内部 request 并交给 <see cref="ICqrsRuntime" />
/// 以复用统一的 dispatch / pipeline 入口;否则回退到 legacy 直接执行。
/// </summary>
/// <typeparam name="TResult">查询结果的类型。</typeparam>
/// <param name="query">要执行的查询对象,必须实现 IQuery&lt;TResult&gt; 接口。</param>
/// <returns>查询执行的结果,类型为 TResult。</returns>
public TResult Send<TResult>(IQuery<TResult> query)
{
ArgumentNullException.ThrowIfNull(query);
if (TryResolveDispatchContext(query, out var context))
{
var boxedResult = _runtime.SendAsync(
context,
new LegacyQueryDispatchRequest(
query,
() => query.Do()))
.AsTask()
.GetAwaiter()
.GetResult();
return (TResult)boxedResult!;
}
return query.Do();
}
/// <summary>
/// 解析当前 legacy 查询应该绑定到哪个架构上下文。
/// </summary>
/// <param name="query">即将执行的 legacy 查询对象。</param>
/// <param name="context">命中时返回可用于 CQRS runtime 的架构上下文。</param>
/// <returns>如果既接入了 runtime 且查询对象提供了上下文,则返回 <see langword="true" />。</returns>
[MemberNotNullWhen(true, nameof(_runtime))]
private bool TryResolveDispatchContext(
object query,
out GFramework.Core.Abstractions.Architectures.IArchitectureContext context)
{
context = null!;
if (_runtime is null || query is not IContextAware contextAware)
{
return false;
}
try
{
context = contextAware.GetContext();
return true;
}
catch (InvalidOperationException)
{
return false;
}
}
}