// Copyright (c) 2025-2026 GeWuYou // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using GFramework.Core.Abstractions.Architectures; using GFramework.Core.Abstractions.Rule; using GFramework.Cqrs.Abstractions.Cqrs; namespace GFramework.Core.Cqrs; /// /// 为 legacy Core CQRS bridge 提供共享的上下文解析与同步兼容辅助逻辑。 /// /// /// 旧的同步 Command/Query 入口仍需要阻塞等待统一 返回结果。 /// 这里统一通过 把等待动作切换到线程池, /// 避免直接占用调用方的 导致 legacy 同步入口与异步 pipeline 互相卡死。 /// internal static class LegacyCqrsDispatchHelper { /// /// 解析当前 legacy 目标对象是否能够绑定到统一 CQRS runtime 的架构上下文。 /// /// 当前执行器可用的统一 CQRS runtime。 /// 即将执行的 legacy 目标对象。 /// 命中时返回可用于 CQRS runtime 的架构上下文。 /// /// 当 可用且 能稳定提供 /// 时返回 ;否则返回 。 /// internal static bool TryResolveDispatchContext( [NotNullWhen(true)] ICqrsRuntime? runtime, object target, out IArchitectureContext context) { ArgumentNullException.ThrowIfNull(target); context = null!; if (runtime is null || target is not IContextAware contextAware) { return false; } try { context = contextAware.GetContext(); return true; } catch (InvalidOperationException exception) when (IsMissingContextException(exception)) { return false; } } /// /// 判断当前 是否表示 legacy 目标尚未具备可桥接的架构上下文。 /// /// 抛出的异常。 /// /// 仅当异常明确表示“上下文尚未设置”或“当前没有活动上下文”时返回 ; /// 其他运行时错误必须继续向上传播,避免把真实故障误判为可安全回退。 /// private static bool IsMissingContextException(InvalidOperationException exception) { ArgumentNullException.ThrowIfNull(exception); return string.Equals( exception.Message, "Architecture context has not been set. Call SetContext before accessing the context.", StringComparison.Ordinal) || string.Equals( exception.Message, "No active architecture context is currently bound.", StringComparison.Ordinal); } /// /// 同步等待统一 CQRS runtime 完成无返回值请求。 /// /// 负责分发当前请求的统一 CQRS runtime。 /// 当前架构上下文。 /// 要同步等待的请求。 internal static void SendSynchronously( ICqrsRuntime runtime, IArchitectureContext context, IRequest request) { ArgumentNullException.ThrowIfNull(runtime); ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(request); Task.Run(() => runtime.SendAsync(context, request).AsTask()).GetAwaiter().GetResult(); } /// /// 同步等待统一 CQRS runtime 完成带返回值请求,并返回实际响应。 /// /// 请求响应类型。 /// 负责分发当前请求的统一 CQRS runtime。 /// 当前架构上下文。 /// 要同步等待的请求。 /// 统一 CQRS runtime 返回的响应结果。 internal static TResponse SendSynchronously( ICqrsRuntime runtime, IArchitectureContext context, IRequest request) { ArgumentNullException.ThrowIfNull(runtime); ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(request); return Task.Run(() => runtime.SendAsync(context, request).AsTask()).GetAwaiter().GetResult(); } }