namespace GFramework.Cqrs.SourceGenerators.Cqrs; /// /// 为当前编译程序集生成 CQRS 处理器注册器,以减少运行时的程序集反射扫描成本。 /// public sealed partial class CqrsHandlerRegistryGenerator { private readonly record struct HandlerRegistrationSpec( string HandlerInterfaceDisplayName, string ImplementationTypeDisplayName, string HandlerInterfaceLogName, string ImplementationLogName); private readonly record struct ReflectedImplementationRegistrationSpec( string HandlerInterfaceDisplayName, string HandlerInterfaceLogName); private readonly record struct OrderedRegistrationSpec( string HandlerInterfaceLogName, OrderedRegistrationKind Kind, int Index); private readonly record struct GeneratedRegistrySourceShape( bool HasReflectedImplementationRegistrations, bool HasPreciseReflectedRegistrations, bool HasReflectionTypeLookups, bool HasExternalAssemblyTypeLookups) { public bool RequiresRegistryAssemblyVariable => HasReflectedImplementationRegistrations || HasPreciseReflectedRegistrations || HasReflectionTypeLookups; } /// /// 标记某条 handler 注册语句在生成阶段采用的表达策略。 /// /// /// 该枚举只服务于输出排序与代码分支选择,用来保证生成注册器在“直接注册” /// “反射实现类型查找”和“精确运行时类型解析”之间保持稳定顺序。 /// private enum OrderedRegistrationKind { Direct, ReflectedImplementation, PreciseReflected } /// /// 描述生成注册器中某个运行时类型引用的构造方式。 /// /// /// 某些 handler 服务类型可以直接以 typeof(...) 输出,某些则需要在运行时补充 /// 反射查找、数组封装或泛型实参重建。该记录把这些差异收敛为统一的递归结构, /// 供源码输出阶段生成稳定的类型解析语句。 /// private sealed record RuntimeTypeReferenceSpec( string? TypeDisplayName, string? ReflectionTypeMetadataName, string? ReflectionAssemblyName, RuntimeTypeReferenceSpec? ArrayElementTypeReference, int ArrayRank, RuntimeTypeReferenceSpec? PointerElementTypeReference, RuntimeTypeReferenceSpec? GenericTypeDefinitionReference, ImmutableArray GenericTypeArguments) { /// /// 创建一个可直接通过 typeof(...) 表达的类型引用。 /// public static RuntimeTypeReferenceSpec FromDirectReference(string typeDisplayName) { return new RuntimeTypeReferenceSpec( typeDisplayName, null, null, null, 0, null, null, ImmutableArray.Empty); } /// /// 创建一个需要从当前消费端程序集反射解析的类型引用。 /// public static RuntimeTypeReferenceSpec FromReflectionLookup(string reflectionTypeMetadataName) { return new RuntimeTypeReferenceSpec( null, reflectionTypeMetadataName, null, null, 0, null, null, ImmutableArray.Empty); } /// /// 创建一个需要从被引用程序集反射解析的类型引用。 /// public static RuntimeTypeReferenceSpec FromExternalReflectionLookup( string reflectionAssemblyName, string reflectionTypeMetadataName) { return new RuntimeTypeReferenceSpec( null, reflectionTypeMetadataName, reflectionAssemblyName, null, 0, null, null, ImmutableArray.Empty); } /// /// 创建一个数组类型引用。 /// public static RuntimeTypeReferenceSpec FromArray(RuntimeTypeReferenceSpec elementTypeReference, int arrayRank) { return new RuntimeTypeReferenceSpec( null, null, null, elementTypeReference, arrayRank, null, null, ImmutableArray.Empty); } /// /// 创建一个封闭泛型类型引用。 /// public static RuntimeTypeReferenceSpec FromConstructedGeneric( RuntimeTypeReferenceSpec genericTypeDefinitionReference, ImmutableArray genericTypeArguments) { return new RuntimeTypeReferenceSpec( null, null, null, null, 0, null, genericTypeDefinitionReference, genericTypeArguments); } } private readonly record struct PreciseReflectedRegistrationSpec( string OpenHandlerTypeDisplayName, string HandlerInterfaceLogName, ImmutableArray ServiceTypeArguments); private readonly record struct ImplementationRegistrationSpec( string ImplementationTypeDisplayName, string ImplementationLogName, ImmutableArray DirectRegistrations, ImmutableArray ReflectedImplementationRegistrations, ImmutableArray PreciseReflectedRegistrations, string? ReflectionTypeMetadataName, string? ReflectionFallbackHandlerTypeMetadataName); private readonly struct HandlerCandidateAnalysis : IEquatable { public HandlerCandidateAnalysis( string implementationTypeDisplayName, string implementationLogName, ImmutableArray registrations, ImmutableArray reflectedImplementationRegistrations, ImmutableArray preciseReflectedRegistrations, string? reflectionTypeMetadataName, string? reflectionFallbackHandlerTypeMetadataName) { ImplementationTypeDisplayName = implementationTypeDisplayName; ImplementationLogName = implementationLogName; Registrations = registrations; ReflectedImplementationRegistrations = reflectedImplementationRegistrations; PreciseReflectedRegistrations = preciseReflectedRegistrations; ReflectionTypeMetadataName = reflectionTypeMetadataName; ReflectionFallbackHandlerTypeMetadataName = reflectionFallbackHandlerTypeMetadataName; } public string ImplementationTypeDisplayName { get; } public string ImplementationLogName { get; } public ImmutableArray Registrations { get; } public ImmutableArray ReflectedImplementationRegistrations { get; } public ImmutableArray PreciseReflectedRegistrations { get; } public string? ReflectionTypeMetadataName { get; } public string? ReflectionFallbackHandlerTypeMetadataName { get; } public bool Equals(HandlerCandidateAnalysis other) { if (!string.Equals(ImplementationTypeDisplayName, other.ImplementationTypeDisplayName, StringComparison.Ordinal) || !string.Equals(ImplementationLogName, other.ImplementationLogName, StringComparison.Ordinal) || !string.Equals(ReflectionTypeMetadataName, other.ReflectionTypeMetadataName, StringComparison.Ordinal) || !string.Equals( ReflectionFallbackHandlerTypeMetadataName, other.ReflectionFallbackHandlerTypeMetadataName, StringComparison.Ordinal) || Registrations.Length != other.Registrations.Length || ReflectedImplementationRegistrations.Length != other.ReflectedImplementationRegistrations.Length || PreciseReflectedRegistrations.Length != other.PreciseReflectedRegistrations.Length) { return false; } for (var index = 0; index < Registrations.Length; index++) { if (!Registrations[index].Equals(other.Registrations[index])) return false; } for (var index = 0; index < ReflectedImplementationRegistrations.Length; index++) { if (!ReflectedImplementationRegistrations[index].Equals( other.ReflectedImplementationRegistrations[index])) { return false; } } for (var index = 0; index < PreciseReflectedRegistrations.Length; index++) { if (!PreciseReflectedRegistrations[index].Equals(other.PreciseReflectedRegistrations[index])) return false; } return true; } public override bool Equals(object? obj) { return obj is HandlerCandidateAnalysis other && Equals(other); } public override int GetHashCode() { unchecked { var hashCode = StringComparer.Ordinal.GetHashCode(ImplementationTypeDisplayName); hashCode = (hashCode * 397) ^ StringComparer.Ordinal.GetHashCode(ImplementationLogName); hashCode = (hashCode * 397) ^ (ReflectionTypeMetadataName is null ? 0 : StringComparer.Ordinal.GetHashCode(ReflectionTypeMetadataName)); hashCode = (hashCode * 397) ^ (ReflectionFallbackHandlerTypeMetadataName is null ? 0 : StringComparer.Ordinal.GetHashCode(ReflectionFallbackHandlerTypeMetadataName)); foreach (var registration in Registrations) { hashCode = (hashCode * 397) ^ registration.GetHashCode(); } foreach (var reflectedImplementationRegistration in ReflectedImplementationRegistrations) { hashCode = (hashCode * 397) ^ reflectedImplementationRegistration.GetHashCode(); } foreach (var preciseReflectedRegistration in PreciseReflectedRegistrations) { hashCode = (hashCode * 397) ^ preciseReflectedRegistration.GetHashCode(); } return hashCode; } } } private readonly record struct GenerationEnvironment( bool GenerationEnabled, bool SupportsReflectionFallbackAttribute); }