diff --git a/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs b/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs index f51dde95..2e321993 100644 --- a/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs +++ b/GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs @@ -932,6 +932,10 @@ public class CqrsHandlerRegistryGeneratorTests generatedSource, Does.Contain( "var knownServiceTypes0 = new global::System.Collections.Generic.HashSet();")); + Assert.That( + generatedSource, + Does.Contain( + "// Remaining runtime interface discovery target: GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler")); Assert.That( generatedSource, Does.Contain( diff --git a/GFramework.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs b/GFramework.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs index 3bd3571d..72ce6664 100644 --- a/GFramework.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs +++ b/GFramework.SourceGenerators/Cqrs/CqrsHandlerRegistryGenerator.cs @@ -92,6 +92,8 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator ImmutableArray.CreateBuilder(handlerInterfaces.Length); var preciseReflectedRegistrations = ImmutableArray.CreateBuilder(handlerInterfaces.Length); + var runtimeDiscoveredHandlerInterfaceLogNames = + ImmutableArray.CreateBuilder(handlerInterfaces.Length); var requiresRuntimeInterfaceDiscovery = false; foreach (var handlerInterface in handlerInterfaces) { @@ -128,6 +130,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator // 对这些边角场景保留“已知接口静态注册 + 剩余接口运行时补洞”的组合路径, // 避免单个未知接口把同实现上的其它已知注册全部拖回整实现反射发现。 requiresRuntimeInterfaceDiscovery = true; + runtimeDiscoveredHandlerInterfaceLogNames.Add(GetLogDisplayName(handlerInterface)); } return new HandlerCandidateAnalysis( @@ -137,7 +140,8 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator reflectedImplementationRegistrations.ToImmutable(), preciseReflectedRegistrations.ToImmutable(), canReferenceImplementation ? null : GetReflectionTypeMetadataName(type), - requiresRuntimeInterfaceDiscovery); + requiresRuntimeInterfaceDiscovery, + runtimeDiscoveredHandlerInterfaceLogNames.ToImmutable()); } private static void Execute(SourceProductionContext context, GenerationEnvironment generationEnvironment, @@ -182,7 +186,8 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator candidate.ReflectedImplementationRegistrations, candidate.PreciseReflectedRegistrations, candidate.ReflectionTypeMetadataName, - candidate.RequiresRuntimeInterfaceDiscovery)); + candidate.RequiresRuntimeInterfaceDiscovery, + candidate.RuntimeDiscoveredHandlerInterfaceLogNames)); } registrations.Sort(static (left, right) => @@ -655,6 +660,13 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator builder.Append(" var "); builder.Append(knownServiceTypesVariableName); builder.AppendLine(" = new global::System.Collections.Generic.HashSet();"); + foreach (var runtimeDiscoveredHandlerInterfaceLogName in registration + .RuntimeDiscoveredHandlerInterfaceLogNames) + { + builder.Append(" // Remaining runtime interface discovery target: "); + builder.Append(runtimeDiscoveredHandlerInterfaceLogName); + builder.AppendLine(); + } } foreach (var orderedRegistration in orderedRegistrations) @@ -1090,7 +1102,8 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator ImmutableArray ReflectedImplementationRegistrations, ImmutableArray PreciseReflectedRegistrations, string? ReflectionTypeMetadataName, - bool RequiresRuntimeInterfaceDiscovery); + bool RequiresRuntimeInterfaceDiscovery, + ImmutableArray RuntimeDiscoveredHandlerInterfaceLogNames); private readonly struct HandlerCandidateAnalysis : IEquatable { @@ -1101,7 +1114,8 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator ImmutableArray reflectedImplementationRegistrations, ImmutableArray preciseReflectedRegistrations, string? reflectionTypeMetadataName, - bool requiresRuntimeInterfaceDiscovery) + bool requiresRuntimeInterfaceDiscovery, + ImmutableArray runtimeDiscoveredHandlerInterfaceLogNames) { ImplementationTypeDisplayName = implementationTypeDisplayName; ImplementationLogName = implementationLogName; @@ -1110,6 +1124,7 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator PreciseReflectedRegistrations = preciseReflectedRegistrations; ReflectionTypeMetadataName = reflectionTypeMetadataName; RequiresRuntimeInterfaceDiscovery = requiresRuntimeInterfaceDiscovery; + RuntimeDiscoveredHandlerInterfaceLogNames = runtimeDiscoveredHandlerInterfaceLogNames; } public string ImplementationTypeDisplayName { get; } @@ -1126,6 +1141,8 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator public bool RequiresRuntimeInterfaceDiscovery { get; } + public ImmutableArray RuntimeDiscoveredHandlerInterfaceLogNames { get; } + public bool Equals(HandlerCandidateAnalysis other) { if (!string.Equals(ImplementationTypeDisplayName, other.ImplementationTypeDisplayName, @@ -1136,7 +1153,9 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator RequiresRuntimeInterfaceDiscovery != other.RequiresRuntimeInterfaceDiscovery || Registrations.Length != other.Registrations.Length || ReflectedImplementationRegistrations.Length != other.ReflectedImplementationRegistrations.Length || - PreciseReflectedRegistrations.Length != other.PreciseReflectedRegistrations.Length) + PreciseReflectedRegistrations.Length != other.PreciseReflectedRegistrations.Length || + RuntimeDiscoveredHandlerInterfaceLogNames.Length != + other.RuntimeDiscoveredHandlerInterfaceLogNames.Length) { return false; } @@ -1160,6 +1179,17 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator return false; } + for (var index = 0; index < RuntimeDiscoveredHandlerInterfaceLogNames.Length; index++) + { + if (!string.Equals( + RuntimeDiscoveredHandlerInterfaceLogNames[index], + other.RuntimeDiscoveredHandlerInterfaceLogNames[index], + StringComparison.Ordinal)) + { + return false; + } + } + return true; } @@ -1194,6 +1224,12 @@ public sealed class CqrsHandlerRegistryGenerator : IIncrementalGenerator hashCode = (hashCode * 397) ^ preciseReflectedRegistration.GetHashCode(); } + foreach (var runtimeDiscoveredHandlerInterfaceLogName in RuntimeDiscoveredHandlerInterfaceLogNames) + { + hashCode = (hashCode * 397) ^ + StringComparer.Ordinal.GetHashCode(runtimeDiscoveredHandlerInterfaceLogName); + } + return hashCode; } }