GFramework/GFramework.Cqrs/Internal/DefaultCqrsRegistrationService.cs
gewuyou ff553977e3 chore(license): 补齐 Apache-2.0 文件头治理
- 新增许可证文件头检查与修复脚本

- 补充维护者手动修复 PR 工作流和 CI 校验

- 更新贡献指南中的文件头说明

- 补齐仓库维护源码和配置文件的许可证声明
2026-05-03 19:39:49 +08:00

66 lines
2.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
using GFramework.Core.Abstractions.Logging;
using GFramework.Cqrs.Abstractions.Cqrs;
namespace GFramework.Cqrs.Internal;
/// <summary>
/// 默认的 CQRS 程序集注册协调器。
/// </summary>
/// <remarks>
/// 该实现把“按稳定程序集键去重”和“委托给 handler registrar 执行实际映射注册”收敛到 CQRS runtime 内部,
/// 避免外层容器继续了解 handler 注册流水线的内部结构。
/// <para>
/// 该类型不是线程安全的。调用方应在外部同步边界内访问 <see cref="RegisterHandlers" />
/// 例如由容器写锁串行化程序集注册流程。
/// </para>
/// </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();
}
}