// Copyright (c) 2025-2026 GeWuYou // SPDX-License-Identifier: Apache-2.0 using GFramework.Core.Abstractions.Command; using GFramework.Core.Cqrs; using GFramework.Cqrs.Abstractions.Cqrs; using IAsyncCommand = GFramework.Core.Abstractions.Command.IAsyncCommand; namespace GFramework.Core.Command; /// /// 表示一个命令执行器,用于执行命令操作。 /// 该类实现了 ICommandExecutor 接口,提供命令执行的核心功能。 /// public sealed class CommandExecutor(ICqrsRuntime? runtime = null) : ICommandExecutor { private readonly ICqrsRuntime? _runtime = runtime; /// /// 获取当前执行器是否已接入统一 CQRS runtime。 /// /// /// 当调用方只是直接 new 一个执行器做纯单元测试时,这里允许为空,并回退到 legacy 直接执行路径; /// 当执行器由架构容器提供给 使用时,应始终传入 runtime, /// 以便旧入口也复用统一 pipeline 与 handler 调度链路。 /// public bool UsesCqrsRuntime => _runtime is not null; /// /// 发送并执行无返回值的命令 /// /// 要执行的命令对象,不能为空 /// 当command参数为null时抛出 public void Send(ICommand command) { ArgumentNullException.ThrowIfNull(command); if (TryExecuteThroughCqrsRuntime(command, static currentCommand => new LegacyCommandDispatchRequest(currentCommand))) { return; } command.Execute(); } /// /// 发送并执行有返回值的命令 /// /// 命令执行结果的类型 /// 要执行的命令对象,不能为空 /// 命令执行的结果 /// 当command参数为null时抛出 public TResult Send(ICommand command) { ArgumentNullException.ThrowIfNull(command); if (TryExecuteThroughCqrsRuntime( command, static currentCommand => new LegacyCommandResultDispatchRequest( currentCommand, () => currentCommand.Execute()), out TResult? result)) { return result!; } return command.Execute(); } /// /// 发送并异步执行无返回值的命令 /// /// 要执行的命令对象,不能为空 /// 当command参数为null时抛出 public Task SendAsync(IAsyncCommand command) { ArgumentNullException.ThrowIfNull(command); var cqrsRuntime = _runtime; if (LegacyCqrsDispatchHelper.TryResolveDispatchContext(cqrsRuntime, command, out var context)) { return cqrsRuntime.SendAsync(context, new LegacyAsyncCommandDispatchRequest(command)).AsTask(); } return command.ExecuteAsync(); } /// /// 发送并异步执行有返回值的命令 /// /// 命令执行结果的类型 /// 要执行的命令对象,不能为空 /// 命令执行的结果 /// 当command参数为null时抛出 public Task SendAsync(IAsyncCommand command) { ArgumentNullException.ThrowIfNull(command); var cqrsRuntime = _runtime; if (LegacyCqrsDispatchHelper.TryResolveDispatchContext(cqrsRuntime, command, out var context)) { return BridgeAsyncCommandWithResultAsync(cqrsRuntime, context, command); } return command.ExecuteAsync(); } /// /// 尝试通过统一 CQRS runtime 执行当前 legacy 请求。 /// /// legacy 目标对象类型。 /// bridge request 类型。 /// 即将执行的 legacy 目标对象。 /// 用于创建 bridge request 的工厂。 /// 若成功切入 CQRS runtime 则返回 ;否则返回 private bool TryExecuteThroughCqrsRuntime( TTarget target, Func requestFactory) where TTarget : class where TRequest : IRequest { var cqrsRuntime = _runtime; if (!LegacyCqrsDispatchHelper.TryResolveDispatchContext(cqrsRuntime, target, out var context)) { return false; } LegacyCqrsDispatchHelper.SendSynchronously(cqrsRuntime, context, requestFactory(target)); return true; } /// /// 尝试通过统一 CQRS runtime 执行当前 legacy 请求,并返回装箱结果。 /// /// legacy 目标对象类型。 /// 预期结果类型。 /// bridge request 类型。 /// 即将执行的 legacy 目标对象。 /// 用于创建 bridge request 的工厂。 /// 若命中 bridge,则返回执行结果;否则返回默认值。 /// 若成功切入 CQRS runtime 则返回 ;否则返回 private bool TryExecuteThroughCqrsRuntime( TTarget target, Func requestFactory, out TResult? result) where TTarget : class where TRequest : IRequest { var cqrsRuntime = _runtime; if (!LegacyCqrsDispatchHelper.TryResolveDispatchContext(cqrsRuntime, target, out var context)) { result = default; return false; } var boxedResult = LegacyCqrsDispatchHelper.SendSynchronously(cqrsRuntime, context, requestFactory(target)); result = (TResult)boxedResult!; return true; } /// /// 通过统一 CQRS runtime 异步执行 legacy 带返回值命令,并把装箱结果还原为目标类型。 /// /// 命令返回值类型。 /// 负责调度当前 bridge request 的统一 CQRS runtime。 /// 当前架构上下文。 /// 要桥接的 legacy 命令。 /// 命令执行结果。 private static async Task BridgeAsyncCommandWithResultAsync( ICqrsRuntime runtime, GFramework.Core.Abstractions.Architectures.IArchitectureContext context, IAsyncCommand command) { var boxedResult = await runtime.SendAsync( context, new LegacyAsyncCommandResultDispatchRequest( command, async () => await command.ExecuteAsync().ConfigureAwait(false))) .ConfigureAwait(false); return (TResult)boxedResult!; } }