using System.Reflection; using GFramework.Core.Abstractions.Logging; using GFramework.Core.Ioc; using GFramework.Cqrs.Abstractions.Cqrs; namespace GFramework.Cqrs.Tests.Cqrs; /// /// 模拟 generated registry 在实现类型隐藏、但 stream handler interface 可见时,仍提供 stream invoker 元数据。 /// internal sealed class HiddenImplementationGeneratedStreamInvokerProviderRegistry : ICqrsHandlerRegistry, ICqrsStreamInvokerProvider, IEnumeratesCqrsStreamInvokerDescriptors { private static readonly Type HandlerContractType = typeof(IStreamRequestHandler); private static readonly CqrsStreamInvokerDescriptor Descriptor = new( HandlerContractType, typeof(HiddenImplementationGeneratedStreamInvokerProviderRegistry).GetMethod( nameof(InvokeGenerated), BindingFlags.NonPublic | BindingFlags.Static)!); private static readonly CqrsStreamInvokerDescriptorEntry DescriptorEntry = new( typeof(HiddenImplementationStreamInvokerContainer.VisibleStreamRequest), typeof(int), Descriptor); /// /// 通过可见 stream handler interface 把隐藏实现类型注册进目标服务集合,模拟 generator 的 reflected-implementation 路径。 /// /// 承载处理器映射的服务集合。 /// 用于记录注册诊断的日志器。 public void Register(IServiceCollection services, ILogger logger) { ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(logger); var implementationType = HiddenImplementationStreamInvokerContainer.HiddenHandlerType; services.AddTransient(HandlerContractType, implementationType); logger.Debug( $"Registered CQRS handler {implementationType.FullName} as {HandlerContractType.FullName}."); } /// /// 尝试返回指定 stream request/response 类型对对应的 generated invoker 描述符。 /// /// 流式请求运行时类型。 /// 流式响应元素类型。 /// 命中时返回的描述符。 /// 若类型对匹配当前测试流式请求则返回 public bool TryGetDescriptor( Type requestType, Type responseType, out CqrsStreamInvokerDescriptor? descriptor) { if (requestType == typeof(HiddenImplementationStreamInvokerContainer.VisibleStreamRequest) && responseType == typeof(int)) { descriptor = Descriptor; return true; } descriptor = null; return false; } /// /// 返回当前 registry 暴露的全部 generated stream invoker 描述符。 /// /// 单条 hidden implementation stream invoker 描述符条目。 public IReadOnlyList GetDescriptors() { return [DescriptorEntry]; } /// /// 模拟 generated stream invoker 在隐藏实现类型场景下直接执行后的返回值。 /// /// 当前流式请求处理器实例。 /// 当前测试流式请求。 /// 取消令牌。 /// 带有 hidden generated 语义的异步流,便于断言 dispatcher 命中了 generated provider 路径。 private static object InvokeGenerated(object handler, object request, CancellationToken cancellationToken) { _ = handler as IStreamRequestHandler ?? throw new InvalidOperationException("Generated stream invoker received an incompatible hidden handler instance."); var typedRequest = (HiddenImplementationStreamInvokerContainer.VisibleStreamRequest)request; return StreamResultsAsync(typedRequest.Start, cancellationToken); } /// /// 构造供测试断言使用的固定异步流结果。 /// private static async IAsyncEnumerable StreamResultsAsync( int start, [EnumeratorCancellation] CancellationToken cancellationToken) { yield return start * 100; await Task.Yield(); cancellationToken.ThrowIfCancellationRequested(); yield return start * 100 + 1; } }