GFramework/GFramework.Cqrs/Internal/DefaultCqrsRegistrationService.cs
GeWuYou a7604de804 feat(ioc): 添加 Microsoft DI 容器适配器和 CQRS 运行时模块
- 实现 MicrosoftDiContainer 类,提供对 Microsoft.Extensions.DependencyInjection 的适配
- 添加线程安全的依赖注入容器功能,支持单例、瞬态和作用域服务注册
- 实现 CqrsRuntimeModule 模块,用于注册 CQRS 运行时组件
- 添加 CqrsRuntimeFactory 工厂类,提供 CQRS 运行时实现的创建入口
- 实现 DefaultCqrsRegistrationService,处理 CQRS 处理器的程序集注册
- 添加 CqrsTestRuntime 测试工具类,为测试环境提供 CQRS 运行时访问
- 支持多种注册方式包括实例注册、类型映射和工厂方法
- 实现服务获取、查询和生命周期管理功能
- 添加容器冻结机制以构建服务提供者
- 支持 CQRS 管道行为和处理器的批量注册功能
2026-04-16 08:37:40 +08:00

60 lines
2.4 KiB
C#

using System.Reflection;
using GFramework.Core.Abstractions.Logging;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Cqrs.Internal;
/// <summary>
/// 默认的 CQRS 程序集注册协调器。
/// </summary>
/// <remarks>
/// 该实现把“按稳定程序集键去重”和“委托给 handler registrar 执行实际映射注册”收敛到 CQRS runtime 内部,
/// 避免外层容器继续了解 handler 注册流水线的内部结构。
/// </remarks>
internal sealed class DefaultCqrsRegistrationService(ICqrsHandlerRegistrar registrar, ILogger logger)
: ICqrsRegistrationService
{
private readonly ILogger _logger = logger ?? throw new ArgumentNullException(nameof(logger));
private readonly HashSet<string> _registeredAssemblyKeys = new(StringComparer.Ordinal);
private readonly ICqrsHandlerRegistrar _registrar = registrar ?? throw new ArgumentNullException(nameof(registrar));
/// <summary>
/// 注册指定程序集中的 CQRS handlers。
/// </summary>
/// <param name="assemblies">要接入的程序集集合。</param>
public void RegisterHandlers(IEnumerable<Assembly> assemblies)
{
ArgumentNullException.ThrowIfNull(assemblies);
var processedAssemblyKeys = new HashSet<string>(StringComparer.Ordinal);
foreach (var assembly in assemblies
.Where(static assembly => assembly is not null)
.OrderBy(GetAssemblyRegistrationKey, StringComparer.Ordinal))
{
var assemblyKey = GetAssemblyRegistrationKey(assembly);
if (!processedAssemblyKeys.Add(assemblyKey))
continue;
if (_registeredAssemblyKeys.Contains(assemblyKey))
{
_logger.Debug(
$"Skipping CQRS handler registration for assembly {assemblyKey} because it was already registered.");
continue;
}
_registrar.RegisterHandlers([assembly]);
_registeredAssemblyKeys.Add(assemblyKey);
}
}
/// <summary>
/// 生成稳定程序集键,避免相同程序集被不同 <see cref="Assembly" /> 实例重复接入。
/// </summary>
/// <param name="assembly">目标程序集。</param>
/// <returns>稳定的程序集标识。</returns>
private static string GetAssemblyRegistrationKey(Assembly assembly)
{
return assembly.FullName ?? assembly.GetName().Name ?? assembly.ToString();
}
}