// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
using System;
using System.Collections.Generic;
using System.Linq;
using GFramework.Core.Abstractions.Bases;
using GFramework.Core.Abstractions.Ioc;
using GFramework.Core.Abstractions.Rule;
using GFramework.Core.Abstractions.Systems;
using GFramework.Core.Ioc;
using Microsoft.Extensions.DependencyInjection;
namespace GFramework.Cqrs.Benchmarks.Messaging;
///
/// 把冻结后的 benchmark 根容器适配成可重复进入的 request 级解析视图。
///
///
/// `CqrsDispatcher` 会直接依赖 做 handler / pipeline 解析,
/// 因此 request lifetime benchmark 需要一个既保留根容器注册元数据,又能在每次 benchmark 调用时把实例解析切换到
/// 显式作用域 provider 的最小适配层。该类型只覆盖 benchmark 当前 request 路径会使用到的解析相关入口;
/// 任何注册、清空或冻结修改操作都应继续发生在根容器构建阶段,因此这里统一拒绝可变更 API。
///
internal sealed class ScopedBenchmarkContainer : IIocContainer
{
private readonly MicrosoftDiContainer _rootContainer;
private IServiceScope? _activeScope;
private IServiceProvider? _scopedProvider;
///
/// 初始化一个绑定到单个 request 作用域的 benchmark 容器适配器。
///
/// 已冻结的 benchmark 根容器。
internal ScopedBenchmarkContainer(MicrosoftDiContainer rootContainer)
{
_rootContainer = rootContainer ?? throw new ArgumentNullException(nameof(rootContainer));
}
///
/// 为当前 benchmark 调用创建并持有一个新的 request 级作用域。
///
/// 离开作用域时负责释放本次 request 级作用域的租约。
/// 当前适配器仍持有上一次尚未释放的作用域。
internal ScopeLease EnterScope()
{
if (_activeScope is not null)
{
throw new InvalidOperationException(
"Scoped benchmark containers do not support overlapping active scopes.");
}
_activeScope = _rootContainer.CreateScope();
_scopedProvider = _activeScope.ServiceProvider;
return new ScopeLease(this);
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 实例类型。
/// 原本要注册到根容器中的单例实例。
/// 当前适配器始终为只读视图。
public void RegisterSingleton(T instance)
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 服务契约类型。
/// 服务实现类型。
/// 当前适配器始终为只读视图。
public void RegisterSingleton()
where TImpl : class, TService
where TService : class
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 服务契约类型。
/// 服务实现类型。
/// 当前适配器始终为只读视图。
public void RegisterTransient()
where TImpl : class, TService
where TService : class
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 服务契约类型。
/// 服务实现类型。
/// 当前适配器始终为只读视图。
public void RegisterScoped()
where TImpl : class, TService
where TService : class
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 原本要附加到复数注册集合中的实例。
/// 当前适配器始终为只读视图。
public void RegisterPlurality(object instance)
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 复数注册项类型。
/// 当前适配器始终为只读视图。
public void RegisterPlurality() where T : class
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 原本要注册到容器中的系统实例。
/// 当前适配器始终为只读视图。
public void RegisterSystem(ISystem system)
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 实例类型。
/// 原本要注册到容器中的实例。
/// 当前适配器始终为只读视图。
public void Register(T instance)
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 原本要绑定的服务类型。
/// 原本要绑定到该类型的实例。
/// 当前适配器始终为只读视图。
public void Register(Type type, object instance)
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 工厂要创建的服务类型。
/// 原本要注册的工厂委托。
/// 当前适配器始终为只读视图。
public void RegisterFactory(Func factory) where TService : class
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 原本要注册的 request pipeline 行为类型。
/// 当前适配器始终为只读视图。
public void RegisterCqrsPipelineBehavior() where TBehavior : class
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 原本要注册的 stream pipeline 行为类型。
/// 当前适配器始终为只读视图。
public void RegisterCqrsStreamPipelineBehavior() where TBehavior : class
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 原本要扫描 CQRS handler 的程序集。
/// 当前适配器始终为只读视图。
public void RegisterCqrsHandlersFromAssembly(System.Reflection.Assembly assembly)
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持在 request 作用域内追加注册。
///
/// 原本要扫描 CQRS handler 的程序集集合。
/// 当前适配器始终为只读视图。
public void RegisterCqrsHandlersFromAssemblies(IEnumerable assemblies)
{
throw CreateMutationNotSupportedException();
}
///
/// 当前适配器不支持执行额外的服务配置钩子。
///
/// 原本要执行的服务配置委托。
/// 当前适配器始终为只读视图。
public void ExecuteServicesHook(Action? configurator = null)
{
throw CreateMutationNotSupportedException();
}
///
/// 从当前 request 作用域解析单个服务实例。
///
/// 目标服务类型。
/// 解析到的服务实例;若当前作用域未注册则返回 。
/// 调用方尚未通过 激活作用域。
public T? Get() where T : class
{
return GetScopedProvider().GetService();
}
///
/// 从当前 request 作用域解析单个服务实例。
///
/// 目标服务类型。
/// 解析到的服务实例;若当前作用域未注册则返回 。
/// 为 。
/// 调用方尚未通过 激活作用域。
public object? Get(Type type)
{
ArgumentNullException.ThrowIfNull(type);
return GetScopedProvider().GetService(type);
}
///
/// 从当前 request 作用域解析必需的单个服务实例。
///
/// 目标服务类型。
/// 解析到的服务实例。
///
/// 调用方尚未通过 激活作用域,或当前作用域缺少必需服务。
///
public T GetRequired() where T : class
{
return GetScopedProvider().GetRequiredService();
}
///
/// 从当前 request 作用域解析必需的单个服务实例。
///
/// 目标服务类型。
/// 解析到的服务实例。
/// 为 。
///
/// 调用方尚未通过 激活作用域,或当前作用域缺少必需服务。
///
public object GetRequired(Type type)
{
ArgumentNullException.ThrowIfNull(type);
return GetScopedProvider().GetRequiredService(type);
}
///
/// 从当前 request 作用域解析全部服务实例。
///
/// 目标服务类型。
/// 当前作用域中该服务类型的全部实例。
/// 调用方尚未通过 激活作用域。
public IReadOnlyList GetAll() where T : class
{
return GetScopedProvider().GetServices().ToList();
}
///
/// 从当前 request 作用域解析全部服务实例。
///
/// 目标服务类型。
/// 当前作用域中该服务类型的全部实例。
/// 为 。
/// 调用方尚未通过 激活作用域。
public IReadOnlyList