// 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 需要一个既保留根容器注册元数据,又把实例解析切换到显式作用域 provider /// 的最小适配层。该类型只覆盖 benchmark 当前 request 路径会使用到的解析相关入口; /// 任何注册、清空或冻结修改操作都应继续发生在根容器构建阶段,因此这里统一拒绝可变更 API。 /// internal sealed class ScopedBenchmarkContainer : IIocContainer { private readonly MicrosoftDiContainer _rootContainer; private readonly IServiceProvider _scopedProvider; /// /// 初始化一个绑定到单个 request 作用域的 benchmark 容器适配器。 /// /// 已冻结的 benchmark 根容器。 /// 当前 request 独占的作用域实例。 internal ScopedBenchmarkContainer(MicrosoftDiContainer rootContainer, IServiceScope scope) { _rootContainer = rootContainer ?? throw new ArgumentNullException(nameof(rootContainer)); ArgumentNullException.ThrowIfNull(scope); _scopedProvider = scope.ServiceProvider; } /// /// 当前适配器不支持在 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 作用域内追加注册。 /// public void RegisterCqrsPipelineBehavior() where TBehavior : class { throw CreateMutationNotSupportedException(); } /// /// 当前适配器不支持在 request 作用域内追加注册。 /// public void RegisterCqrsStreamPipelineBehavior() where TBehavior : class { throw CreateMutationNotSupportedException(); } /// /// 当前适配器不支持在 request 作用域内追加注册。 /// public void RegisterCqrsHandlersFromAssembly(System.Reflection.Assembly assembly) { throw CreateMutationNotSupportedException(); } /// /// 当前适配器不支持在 request 作用域内追加注册。 /// public void RegisterCqrsHandlersFromAssemblies(IEnumerable assemblies) { throw CreateMutationNotSupportedException(); } /// /// 当前适配器不支持执行额外的服务配置钩子。 /// public void ExecuteServicesHook(Action? configurator = null) { throw CreateMutationNotSupportedException(); } /// /// 从当前 request 作用域解析单个服务实例。 /// public T? Get() where T : class { return _scopedProvider.GetService(); } /// /// 从当前 request 作用域解析单个服务实例。 /// public object? Get(Type type) { ArgumentNullException.ThrowIfNull(type); return _scopedProvider.GetService(type); } /// /// 从当前 request 作用域解析必需的单个服务实例。 /// public T GetRequired() where T : class { return _scopedProvider.GetRequiredService(); } /// /// 从当前 request 作用域解析必需的单个服务实例。 /// public object GetRequired(Type type) { ArgumentNullException.ThrowIfNull(type); return _scopedProvider.GetRequiredService(type); } /// /// 从当前 request 作用域解析全部服务实例。 /// public IReadOnlyList GetAll() where T : class { return _scopedProvider.GetServices().ToList(); } /// /// 从当前 request 作用域解析全部服务实例。 /// public IReadOnlyList GetAll(Type type) { ArgumentNullException.ThrowIfNull(type); return _scopedProvider.GetServices(type).Where(static service => service is not null).Cast().ToList(); } /// /// 从当前 request 作用域解析全部服务实例,并按调用方比较器排序。 /// public IReadOnlyList GetAllSorted(Comparison comparison) where T : class { ArgumentNullException.ThrowIfNull(comparison); var services = GetAll().ToList(); services.Sort(comparison); return services; } /// /// 从当前 request 作用域解析全部服务实例,并按优先级排序。 /// public IReadOnlyList GetAllByPriority() where T : class { return SortByPriority(GetAll()); } /// /// 从当前 request 作用域解析全部服务实例,并按优先级排序。 /// public IReadOnlyList GetAllByPriority(Type type) { ArgumentNullException.ThrowIfNull(type); return SortByPriority(GetAll(type)); } /// /// 判断根容器是否声明了目标服务键。 /// /// /// `CqrsDispatcher` 在热路径上先做注册存在性判断,再决定是否枚举 pipeline;这里沿用根容器冻结后的注册视图, /// 避免把“当前 scope 还未物化实例”误判成“没有注册该行为”。 /// public bool HasRegistration(Type type) { ArgumentNullException.ThrowIfNull(type); return _rootContainer.HasRegistration(type); } /// /// 判断根容器是否声明了目标服务键。 /// public bool Contains() where T : class { return _rootContainer.Contains(); } /// /// 当前 request 作用域适配器不追踪实例归属。 /// public bool ContainsInstance(object instance) { return _rootContainer.ContainsInstance(instance); } /// /// 当前适配器不支持清空注册。 /// public void Clear() { throw CreateMutationNotSupportedException(); } /// /// 当前适配器不支持重新冻结。 /// public void Freeze() { throw CreateMutationNotSupportedException(); } /// /// 继续暴露根容器底层服务集合,仅用于接口兼容。 /// public IServiceCollection GetServicesUnsafe => _rootContainer.GetServicesUnsafe; /// /// 基于当前 request 作用域继续创建嵌套作用域。 /// public IServiceScope CreateScope() { return _scopedProvider.CreateScope(); } /// /// 将上下文转发给根容器,保持与 request 生命周期无关的上下文缓存行为一致。 /// public void SetContext(GFramework.Core.Abstractions.Architectures.IArchitectureContext context) { ((IContextAware)_rootContainer).SetContext(context); } /// /// 读取根容器当前持有的架构上下文。 /// public GFramework.Core.Abstractions.Architectures.IArchitectureContext GetContext() { return ((IContextAware)_rootContainer).GetContext(); } /// /// 释放当前 request 适配器时不拥有作用域;外层 benchmark 调度入口负责统一释放。 /// public void Dispose() { } /// /// 生成统一的只读适配器异常,避免 benchmark 误把 request 级容器当成可变组合根。 /// private static InvalidOperationException CreateMutationNotSupportedException() { return new InvalidOperationException( "Scoped benchmark containers are read-only request views. Mutate registrations on the root benchmark host before freezing it."); } /// /// 复用与根容器一致的优先级排序语义。 /// /// 服务实例类型。 /// 待排序服务集合。 /// 按优先级稳定排序后的服务列表。 private static IReadOnlyList SortByPriority(IReadOnlyList services) where T : class { if (services.Count <= 1) { return services; } return services .Select((service, index) => new { Service = service, Index = index }) .OrderBy(static x => { var priority = x.Service is IPrioritized prioritized ? prioritized.Priority : 0; return (priority, x.Index); }) .Select(static x => x.Service) .ToList(); } }