// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
using System;
using System.Linq;
using GFramework.Core.Ioc;
using GFramework.Cqrs.Abstractions.Cqrs;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
namespace GFramework.Cqrs.Benchmarks.Messaging;
///
/// 为 benchmark 场景构建最小且可重复的 GFramework / MediatR 对照宿主。
///
///
/// 基准工程里的对照目标是“相同消息合同下的调度差异”,而不是程序集扫描量或容器生命周期差异。
/// 因此这里统一封装两类宿主的最小注册形状,确保:
/// 1. GFramework 容器在首次发送前已经冻结,可真实解析按类型注册的 handler;
/// 2. MediatR 只扫描当前 benchmark 明确拥有的 handler / behavior 类型,避免整个程序集的额外注册污染结果。
///
internal static class BenchmarkHostFactory
{
///
/// 创建一个已经冻结的 GFramework benchmark 容器。
///
/// 向容器写入 benchmark 所需 handler / pipeline 的注册动作。
/// 已冻结、可立即用于 runtime 分发的容器。
internal static MicrosoftDiContainer CreateFrozenGFrameworkContainer(Action configure)
{
ArgumentNullException.ThrowIfNull(configure);
var container = new MicrosoftDiContainer();
configure(container);
container.Freeze();
return container;
}
///
/// 创建只承载当前 benchmark handler 集合的最小 MediatR 宿主。
///
/// 补充当前场景的显式服务注册,例如手工单例 handler 或 pipeline 行为。
/// 用于限定扫描程序集的标记类型。
///
/// 仅允许当前 benchmark 场景需要的 handler / behavior 类型通过扫描;
/// 这样可保留 `AddMediatR` 的正常装配路径,同时避免整个基准程序集里的其他 handler 被一并注册。
///
/// 当前 benchmark 希望 MediatR 使用的默认注册生命周期。
/// 只承载当前 benchmark 场景所需服务的 DI 宿主。
internal static ServiceProvider CreateMediatRServiceProvider(
Action? configure,
Type handlerAssemblyMarkerType,
Func handlerTypeFilter,
ServiceLifetime lifetime = ServiceLifetime.Transient)
{
ArgumentNullException.ThrowIfNull(handlerAssemblyMarkerType);
ArgumentNullException.ThrowIfNull(handlerTypeFilter);
var services = new ServiceCollection();
services.AddLogging(static builder =>
Microsoft.Extensions.Logging.FilterLoggingBuilderExtensions.AddFilter(
builder,
"LuckyPennySoftware.MediatR.License",
Microsoft.Extensions.Logging.LogLevel.None));
configure?.Invoke(services);
services.AddMediatR(options =>
{
options.Lifetime = lifetime;
options.TypeEvaluator = handlerTypeFilter;
options.RegisterServicesFromAssembly(handlerAssemblyMarkerType.Assembly);
});
return services.BuildServiceProvider();
}
///
/// 判断某个类型是否正好实现了指定的闭合或开放 MediatR 合同。
///
/// 待判断类型。
/// 目标开放泛型合同,例如 。
/// 命中任一实现接口时返回 ;否则返回 。
internal static bool ImplementsOpenGenericContract(Type candidateType, Type openGenericContract)
{
ArgumentNullException.ThrowIfNull(candidateType);
ArgumentNullException.ThrowIfNull(openGenericContract);
return candidateType.GetInterfaces().Any(interfaceType =>
interfaceType.IsGenericType &&
interfaceType.GetGenericTypeDefinition() == openGenericContract);
}
}