using System.Reflection; using GFramework.Core.Abstractions.Logging; using GFramework.Core.Ioc; using GFramework.Core.Logging; using GFramework.Cqrs.Abstractions.Cqrs; namespace GFramework.Cqrs.Tests.Cqrs; /// /// 模拟同时提供 handler 注册与 request invoker 元数据的 generated registry。 /// internal sealed class GeneratedRequestInvokerProviderRegistry : ICqrsHandlerRegistry, ICqrsRequestInvokerProvider, IEnumeratesCqrsRequestInvokerDescriptors { private static readonly CqrsRequestInvokerDescriptor Descriptor = new( typeof(IRequestHandler), typeof(GeneratedRequestInvokerProviderRegistry).GetMethod( nameof(InvokeGenerated), BindingFlags.NonPublic | BindingFlags.Static)!); private static readonly CqrsRequestInvokerDescriptorEntry DescriptorEntry = new( typeof(GeneratedRequestInvokerRequest), typeof(string), Descriptor); /// /// 将测试请求处理器注册到目标服务集合。 /// /// 承载处理器映射的服务集合。 /// 用于记录注册诊断的日志器。 public void Register(IServiceCollection services, ILogger logger) { ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(logger); services.AddTransient( typeof(IRequestHandler), typeof(GeneratedRequestInvokerRequestHandler)); logger.Debug( $"Registered CQRS handler {typeof(GeneratedRequestInvokerRequestHandler).FullName} as {typeof(IRequestHandler).FullName}."); } /// /// 尝试返回指定 request/response 类型对对应的 generated invoker 描述符。 /// /// 请求运行时类型。 /// 响应运行时类型。 /// 命中时返回的描述符。 /// 若类型对匹配当前测试请求则返回 public bool TryGetDescriptor( Type requestType, Type responseType, out CqrsRequestInvokerDescriptor? descriptor) { if (requestType == typeof(GeneratedRequestInvokerRequest) && responseType == typeof(string)) { descriptor = Descriptor; return true; } descriptor = null; return false; } /// /// 返回当前 registry 暴露的全部 generated request invoker 描述符。 /// /// 单条测试 request invoker 描述符条目。 public IReadOnlyList GetDescriptors() { return [DescriptorEntry]; } /// /// 模拟 generated request invoker 直接执行后的返回值。 /// /// 当前请求处理器实例。 /// 当前测试请求。 /// 取消令牌。 /// 带有 generated 前缀的结果,便于断言 dispatcher 走了 provider 路径。 private static ValueTask InvokeGenerated(object handler, object request, CancellationToken cancellationToken) { _ = handler as IRequestHandler ?? throw new InvalidOperationException("Generated invoker received an incompatible handler instance."); var typedRequest = (GeneratedRequestInvokerRequest)request; return ValueTask.FromResult($"generated:{typedRequest.Value}"); } }