namespace GFramework.Cqrs.SourceGenerators.Cqrs; /// /// 为当前编译程序集生成 CQRS 处理器注册器,以减少运行时的程序集反射扫描成本。 /// public sealed partial class CqrsHandlerRegistryGenerator { private readonly record struct RequestInvokerRegistrationSpec( string RequestTypeDisplayName, string ResponseTypeDisplayName); private readonly record struct StreamInvokerRegistrationSpec( string RequestTypeDisplayName, string ResponseTypeDisplayName); private readonly record struct HandlerRegistrationSpec( string HandlerInterfaceDisplayName, string ImplementationTypeDisplayName, string HandlerInterfaceLogName, string ImplementationLogName, RequestInvokerRegistrationSpec? RequestInvokerRegistration, StreamInvokerRegistrationSpec? StreamInvokerRegistration); 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, bool SupportsRequestInvokerProvider, ImmutableArray RequestInvokerEmissions, bool SupportsStreamInvokerProvider, ImmutableArray StreamInvokerEmissions) { public bool RequiresRegistryAssemblyVariable => HasReflectedImplementationRegistrations || HasPreciseReflectedRegistrations || HasReflectionTypeLookups; public bool HasRequestInvokerProvider => SupportsRequestInvokerProvider && !RequestInvokerEmissions.IsDefaultOrEmpty; public bool HasStreamInvokerProvider => SupportsStreamInvokerProvider && !StreamInvokerEmissions.IsDefaultOrEmpty; } private readonly record struct RequestInvokerEmissionSpec( string RequestTypeDisplayName, string ResponseTypeDisplayName, string HandlerInterfaceDisplayName, int MethodIndex); private readonly record struct StreamInvokerEmissionSpec( string RequestTypeDisplayName, string ResponseTypeDisplayName, string HandlerInterfaceDisplayName, int MethodIndex); /// /// 标记某条 handler 注册语句在生成阶段采用的表达策略。 /// /// /// 该枚举只服务于输出排序与代码分支选择,用来保证生成注册器在“直接注册” /// “反射实现类型查找”和“精确运行时类型解析”之间保持稳定顺序。 /// private enum OrderedRegistrationKind { Direct, ReflectedImplementation, PreciseReflected } /// /// 描述生成注册器中某个运行时类型引用的构造方式。 /// /// /// 某些 handler 服务类型可以直接以 typeof(...) 输出,某些则需要在运行时补充 /// 反射查找、数组封装或泛型实参重建。该记录把这些差异收敛为统一的递归结构, /// 供源码输出阶段生成稳定的类型解析语句。 /// private sealed record RuntimeTypeReferenceSpec( string? TypeDisplayName, string? ReflectionTypeMetadataName, string? ReflectionAssemblyName, RuntimeTypeReferenceSpec? ArrayElementTypeReference, int ArrayRank, RuntimeTypeReferenceSpec? GenericTypeDefinitionReference, ImmutableArray GenericTypeArguments) { /// /// 创建一个可直接通过 typeof(...) 表达的类型引用。 /// public static RuntimeTypeReferenceSpec FromDirectReference(string typeDisplayName) { return new RuntimeTypeReferenceSpec( typeDisplayName, null, null, null, 0, null, ImmutableArray.Empty); } /// /// 创建一个需要从当前消费端程序集反射解析的类型引用。 /// public static RuntimeTypeReferenceSpec FromReflectionLookup(string reflectionTypeMetadataName) { return new RuntimeTypeReferenceSpec( null, reflectionTypeMetadataName, null, null, 0, null, ImmutableArray.Empty); } /// /// 创建一个需要从被引用程序集反射解析的类型引用。 /// public static RuntimeTypeReferenceSpec FromExternalReflectionLookup( string reflectionAssemblyName, string reflectionTypeMetadataName) { return new RuntimeTypeReferenceSpec( null, reflectionTypeMetadataName, reflectionAssemblyName, null, 0, null, ImmutableArray.Empty); } /// /// 创建一个数组类型引用。 /// public static RuntimeTypeReferenceSpec FromArray(RuntimeTypeReferenceSpec elementTypeReference, int arrayRank) { return new RuntimeTypeReferenceSpec( null, null, null, elementTypeReference, arrayRank, null, ImmutableArray.Empty); } /// /// 创建一个封闭泛型类型引用。 /// public static RuntimeTypeReferenceSpec FromConstructedGeneric( RuntimeTypeReferenceSpec genericTypeDefinitionReference, ImmutableArray genericTypeArguments) { return new RuntimeTypeReferenceSpec( null, null, null, null, 0, genericTypeDefinitionReference, genericTypeArguments); } } private readonly record struct PreciseReflectedRegistrationSpec( string OpenHandlerTypeDisplayName, string HandlerInterfaceLogName, ImmutableArray ServiceTypeArguments); /// /// 描述单个程序集级 reflection fallback 特性实例的发射内容。 /// /// /// 某些运行时合同允许生成器把可直接引用的 fallback handlers 与必须按名称恢复的 handlers /// 拆成多个特性实例,以进一步减少运行时字符串查找成本。 /// private readonly record struct ReflectionFallbackAttributeEmissionSpec( bool EmitDirectTypeReferences, ImmutableArray Values); /// /// 描述本轮生成应如何发射程序集级 reflection fallback 元数据。 /// private readonly record struct ReflectionFallbackEmissionSpec( ImmutableArray Attributes) { /// /// 获取当前是否需要发射任何 fallback 元数据。 /// public bool HasFallbackHandlers => !Attributes.IsDefaultOrEmpty; } private readonly record struct ImplementationRegistrationSpec( string ImplementationTypeDisplayName, string ImplementationLogName, ImmutableArray DirectRegistrations, ImmutableArray ReflectedImplementationRegistrations, ImmutableArray PreciseReflectedRegistrations, string? ReflectionTypeMetadataName, string? ReflectionFallbackHandlerTypeDisplayName, string? ReflectionFallbackHandlerTypeMetadataName); private readonly struct HandlerCandidateAnalysis : IEquatable { public HandlerCandidateAnalysis( string implementationTypeDisplayName, string implementationLogName, ImmutableArray registrations, ImmutableArray reflectedImplementationRegistrations, ImmutableArray preciseReflectedRegistrations, string? reflectionTypeMetadataName, string? reflectionFallbackHandlerTypeDisplayName, string? reflectionFallbackHandlerTypeMetadataName) { ImplementationTypeDisplayName = implementationTypeDisplayName; ImplementationLogName = implementationLogName; Registrations = registrations; ReflectedImplementationRegistrations = reflectedImplementationRegistrations; PreciseReflectedRegistrations = preciseReflectedRegistrations; ReflectionTypeMetadataName = reflectionTypeMetadataName; ReflectionFallbackHandlerTypeDisplayName = reflectionFallbackHandlerTypeDisplayName; 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? ReflectionFallbackHandlerTypeDisplayName { 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( ReflectionFallbackHandlerTypeDisplayName, other.ReflectionFallbackHandlerTypeDisplayName, 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) ^ (ReflectionFallbackHandlerTypeDisplayName is null ? 0 : StringComparer.Ordinal.GetHashCode(ReflectionFallbackHandlerTypeDisplayName)); 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 SupportsNamedReflectionFallbackTypes, bool SupportsDirectReflectionFallbackTypes, bool SupportsMultipleReflectionFallbackAttributes, bool SupportsRequestInvokerProvider, bool SupportsStreamInvokerProvider); }