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}");
}
}