namespace GFramework.Cqrs.SourceGenerators.Cqrs; /// /// 为当前编译程序集生成 CQRS 处理器注册器,以减少运行时的程序集反射扫描成本。 /// public sealed partial class CqrsHandlerRegistryGenerator { /// /// 生成程序集级 CQRS handler 注册器源码。 /// /// /// 已整理并排序的 handler 注册描述。方法会据此生成 CqrsHandlerRegistry.g.cs,其中包含直接注册、实现类型反射注册、精确运行时类型查找等分支。 /// /// /// 当前轮次选定的程序集级 reflection fallback 元数据发射策略。 /// 调用方必须先确保:若该策略包含 fallback handlers,则当前 runtime 已声明支持对应的 fallback attribute 契约; /// 否则应在进入本方法前报告诊断并放弃生成,而不是输出会静默漏注册的半成品注册器。 /// /// 完整的注册器源代码文本。 /// /// 当 不包含任何 fallback handlers 时, /// 输出只包含程序集级 CqrsHandlerRegistryAttribute 和注册器实现。 /// 当其包含 fallback handlers 且 runtime 合同可用时,输出还会附带一个或多个程序集级 /// CqrsReflectionFallbackAttribute,让运行时补齐生成阶段无法精确表达的剩余 handler。 /// 该方法本身不报告诊断;“fallback 必需但 runtime 契约缺失”的错误由调用方在进入本方法前处理。 /// private static string GenerateSource( GenerationEnvironment generationEnvironment, IReadOnlyList registrations, ReflectionFallbackEmissionSpec reflectionFallbackEmission) { var sourceShape = CreateGeneratedRegistrySourceShape(generationEnvironment, registrations); var builder = new StringBuilder(); AppendGeneratedSourcePreamble(builder, reflectionFallbackEmission); AppendGeneratedRegistryType(builder, registrations, sourceShape); return builder.ToString(); } /// /// 预先计算生成注册器需要的辅助分支,让主源码发射流程保持线性且避免重复扫描注册集合。 /// /// 已整理并排序的 handler 注册描述。 /// 当前生成输出需要启用的结构分支。 private static GeneratedRegistrySourceShape CreateGeneratedRegistrySourceShape( GenerationEnvironment generationEnvironment, IReadOnlyList registrations) { var hasReflectedImplementationRegistrations = registrations.Any(static registration => !registration.ReflectedImplementationRegistrations.IsDefaultOrEmpty); var hasPreciseReflectedRegistrations = registrations.Any(static registration => !registration.PreciseReflectedRegistrations.IsDefaultOrEmpty); var hasReflectionTypeLookups = registrations.Any(static registration => !string.IsNullOrWhiteSpace(registration.ReflectionTypeMetadataName)); var hasExternalAssemblyTypeLookups = registrations.Any(static registration => registration.PreciseReflectedRegistrations.Any(static preciseRegistration => preciseRegistration.ServiceTypeArguments.Any(ContainsExternalAssemblyTypeLookup))); var requestInvokerEmissions = CreateRequestInvokerEmissions( generationEnvironment.SupportsRequestInvokerProvider, registrations); return new GeneratedRegistrySourceShape( hasReflectedImplementationRegistrations, hasPreciseReflectedRegistrations, hasReflectionTypeLookups, hasExternalAssemblyTypeLookups, generationEnvironment.SupportsRequestInvokerProvider, requestInvokerEmissions); } private static ImmutableArray CreateRequestInvokerEmissions( bool supportsRequestInvokerProvider, IReadOnlyList registrations) { if (!supportsRequestInvokerProvider) return ImmutableArray.Empty; var builder = ImmutableArray.CreateBuilder(); var methodIndex = 0; foreach (var registration in registrations) { foreach (var directRegistration in registration.DirectRegistrations) { if (directRegistration.RequestInvokerRegistration is not { } requestInvokerRegistration) continue; builder.Add(new RequestInvokerEmissionSpec( requestInvokerRegistration.RequestTypeDisplayName, requestInvokerRegistration.ResponseTypeDisplayName, directRegistration.HandlerInterfaceDisplayName, methodIndex++)); } } return builder.ToImmutable(); } /// /// 发射生成文件头、nullable 指令以及注册器所需的程序集级元数据特性。 /// /// 生成源码构造器。 /// 需要写入程序集级 reflection fallback 特性的元数据策略。 private static void AppendGeneratedSourcePreamble( StringBuilder builder, ReflectionFallbackEmissionSpec reflectionFallbackEmission) { builder.AppendLine("// "); builder.AppendLine("#nullable enable"); builder.AppendLine(); if (reflectionFallbackEmission.HasFallbackHandlers) { AppendReflectionFallbackAttributes(builder, reflectionFallbackEmission); builder.AppendLine(); } builder.Append("[assembly: global::"); builder.Append(CqrsRuntimeNamespace); builder.Append(".CqrsHandlerRegistryAttribute(typeof(global::"); builder.Append(GeneratedNamespace); builder.Append('.'); builder.Append(GeneratedTypeName); builder.AppendLine("))]"); } /// /// 发射程序集级 reflection fallback 元数据特性,供运行时补齐生成阶段无法精确表达的 handler。 /// /// 生成源码构造器。 /// 需要写入特性的 fallback 元数据策略。 private static void AppendReflectionFallbackAttributes( StringBuilder builder, ReflectionFallbackEmissionSpec reflectionFallbackEmission) { for (var index = 0; index < reflectionFallbackEmission.Attributes.Length; index++) { if (index > 0) { builder.AppendLine(); } AppendReflectionFallbackAttribute(builder, reflectionFallbackEmission.Attributes[index]); } } /// /// 发射单个程序集级 reflection fallback 元数据特性实例。 /// private static void AppendReflectionFallbackAttribute( StringBuilder builder, ReflectionFallbackAttributeEmissionSpec attributeEmission) { builder.Append("[assembly: global::"); builder.Append(CqrsRuntimeNamespace); builder.Append(".CqrsReflectionFallbackAttribute("); for (var index = 0; index < attributeEmission.Values.Length; index++) { if (index > 0) builder.Append(", "); if (attributeEmission.EmitDirectTypeReferences) { builder.Append("typeof("); builder.Append(attributeEmission.Values[index]); builder.Append(')'); } else { builder.Append('"'); builder.Append(EscapeStringLiteral(attributeEmission.Values[index])); builder.Append('"'); } } builder.Append(")]"); } /// /// 发射生成注册器类型本体,包括 Register 方法和运行时反射辅助方法。 /// /// 生成源码构造器。 /// 已排序的 handler 注册描述。 /// 当前输出需要启用的结构分支。 private static void AppendGeneratedRegistryType( StringBuilder builder, IReadOnlyList registrations, GeneratedRegistrySourceShape sourceShape) { builder.AppendLine(); builder.Append("namespace "); builder.Append(GeneratedNamespace); builder.AppendLine(";"); builder.AppendLine(); builder.Append("internal sealed class "); builder.Append(GeneratedTypeName); builder.Append(" : global::"); builder.Append(CqrsRuntimeNamespace); builder.Append(".ICqrsHandlerRegistry"); if (sourceShape.HasRequestInvokerProvider) { builder.Append(", global::"); builder.Append(CqrsRuntimeNamespace); builder.Append(".ICqrsRequestInvokerProvider, global::"); builder.Append(CqrsRuntimeNamespace); builder.Append(".IEnumeratesCqrsRequestInvokerDescriptors"); } builder.AppendLine(); builder.AppendLine("{"); AppendRegisterMethod(builder, registrations, sourceShape); if (sourceShape.HasRequestInvokerProvider) { builder.AppendLine(); AppendRequestInvokerProviderMembers(builder, sourceShape.RequestInvokerEmissions); } if (sourceShape.HasExternalAssemblyTypeLookups) { builder.AppendLine(); AppendReflectionHelpers(builder); } builder.AppendLine("}"); } /// /// 发射注册器的 Register 方法,保持直接注册和反射注册之间的原始稳定排序。 /// /// 生成源码构造器。 /// 已排序的 handler 注册描述。 /// 当前输出需要启用的结构分支。 private static void AppendRegisterMethod( StringBuilder builder, IReadOnlyList registrations, GeneratedRegistrySourceShape sourceShape) { builder.Append( " public void Register(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::"); builder.Append(LoggingNamespace); builder.AppendLine(".ILogger logger)"); builder.AppendLine(" {"); builder.AppendLine(" if (services is null)"); builder.AppendLine(" throw new global::System.ArgumentNullException(nameof(services));"); builder.AppendLine(" if (logger is null)"); builder.AppendLine(" throw new global::System.ArgumentNullException(nameof(logger));"); if (sourceShape.RequiresRegistryAssemblyVariable) { builder.AppendLine(); builder.Append(" var registryAssembly = typeof(global::"); builder.Append(GeneratedNamespace); builder.Append('.'); builder.Append(GeneratedTypeName); builder.AppendLine(").Assembly;"); } if (registrations.Count > 0) builder.AppendLine(); for (var registrationIndex = 0; registrationIndex < registrations.Count; registrationIndex++) { var registration = registrations[registrationIndex]; if (!registration.ReflectedImplementationRegistrations.IsDefaultOrEmpty || !registration.PreciseReflectedRegistrations.IsDefaultOrEmpty) { AppendOrderedImplementationRegistrations(builder, registration, registrationIndex); } else if (!registration.DirectRegistrations.IsDefaultOrEmpty) { AppendDirectRegistrations(builder, registration); } } builder.AppendLine(" }"); } private static void AppendRequestInvokerProviderMembers( StringBuilder builder, ImmutableArray requestInvokerEmissions) { AppendRequestInvokerDescriptorArray(builder, requestInvokerEmissions); builder.AppendLine(); AppendRequestInvokerProviderMethods(builder); for (var index = 0; index < requestInvokerEmissions.Length; index++) { builder.AppendLine(); AppendRequestInvokerMethod(builder, requestInvokerEmissions[index]); } } private static void AppendRequestInvokerDescriptorArray( StringBuilder builder, ImmutableArray requestInvokerEmissions) { builder.AppendLine(" private static readonly global::GFramework.Cqrs.CqrsRequestInvokerDescriptorEntry[] RequestInvokerDescriptors ="); builder.AppendLine(" ["); for (var index = 0; index < requestInvokerEmissions.Length; index++) { var emission = requestInvokerEmissions[index]; builder.Append(" new global::"); builder.Append(CqrsRuntimeNamespace); builder.Append(".CqrsRequestInvokerDescriptorEntry(typeof("); builder.Append(emission.RequestTypeDisplayName); builder.Append("), typeof("); builder.Append(emission.ResponseTypeDisplayName); builder.Append("), new global::"); builder.Append(CqrsRuntimeNamespace); builder.Append(".CqrsRequestInvokerDescriptor(typeof("); builder.Append(emission.HandlerInterfaceDisplayName); builder.Append("), typeof("); builder.Append(GeneratedTypeName); builder.Append(").GetMethod(nameof(InvokeRequestHandler"); builder.Append(emission.MethodIndex); builder.Append("), global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Static)!))"); builder.AppendLine(index == requestInvokerEmissions.Length - 1 ? string.Empty : ","); } builder.AppendLine(" ];"); } private static void AppendRequestInvokerProviderMethods(StringBuilder builder) { builder.Append(" public global::System.Collections.Generic.IReadOnlyList GetDescriptors()"); builder.AppendLine(" {"); builder.AppendLine(" return RequestInvokerDescriptors;"); builder.AppendLine(" }"); builder.AppendLine(); builder.Append(" public bool TryGetDescriptor(global::System.Type requestType, global::System.Type responseType, out global::"); builder.Append(CqrsRuntimeNamespace); builder.AppendLine(".CqrsRequestInvokerDescriptor? descriptor)"); builder.AppendLine(" {"); builder.AppendLine(" if (requestType is null)"); builder.AppendLine(" throw new global::System.ArgumentNullException(nameof(requestType));"); builder.AppendLine(" if (responseType is null)"); builder.AppendLine(" throw new global::System.ArgumentNullException(nameof(responseType));"); builder.AppendLine(); builder.AppendLine(" foreach (var entry in RequestInvokerDescriptors)"); builder.AppendLine(" {"); builder.AppendLine(" if (entry.RequestType == requestType && entry.ResponseType == responseType)"); builder.AppendLine(" {"); builder.AppendLine(" descriptor = entry.Descriptor;"); builder.AppendLine(" return true;"); builder.AppendLine(" }"); builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine(" descriptor = null;"); builder.AppendLine(" return false;"); builder.AppendLine(" }"); } private static void AppendRequestInvokerMethod(StringBuilder builder, RequestInvokerEmissionSpec emission) { builder.Append(" private static global::System.Threading.Tasks.ValueTask<"); builder.Append(emission.ResponseTypeDisplayName); builder.Append("> InvokeRequestHandler"); builder.Append(emission.MethodIndex); builder.Append("(object handler, object request, global::System.Threading.CancellationToken cancellationToken)"); builder.AppendLine(); builder.AppendLine(" {"); builder.Append(" var typedHandler = ("); builder.Append(emission.HandlerInterfaceDisplayName); builder.AppendLine(")handler;"); builder.Append(" var typedRequest = ("); builder.Append(emission.RequestTypeDisplayName); builder.AppendLine(")request;"); builder.AppendLine(" return typedHandler.Handle(typedRequest, cancellationToken);"); builder.AppendLine(" }"); } private static void AppendDirectRegistrations( StringBuilder builder, ImplementationRegistrationSpec registration) { foreach (var directRegistration in registration.DirectRegistrations) { AppendServiceRegistration( builder, $"typeof({directRegistration.HandlerInterfaceDisplayName})", $"typeof({directRegistration.ImplementationTypeDisplayName})", " "); AppendRegistrationLog( builder, directRegistration.ImplementationLogName, directRegistration.HandlerInterfaceLogName, " "); } } /// /// 发射 AddTransient 调用,调用方负责传入已经按当前分支解析好的 service 和 implementation 表达式。 /// /// 生成源码构造器。 /// 生成代码中的服务类型表达式。 /// 生成代码中的实现类型表达式。 /// 当前生成语句的缩进。 private static void AppendServiceRegistration( StringBuilder builder, string serviceTypeExpression, string implementationTypeExpression, string indent) { builder.Append(indent); builder.AppendLine("global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient("); builder.Append(indent); builder.AppendLine(" services,"); builder.Append(indent); builder.Append(" "); builder.Append(serviceTypeExpression); builder.AppendLine(","); builder.Append(indent); builder.Append(" "); builder.Append(implementationTypeExpression); builder.AppendLine(");"); } /// /// 发射与注册语句配套的调试日志,保持所有生成注册路径的日志文本完全一致。 /// /// 生成源码构造器。 /// 实现类型日志名。 /// handler 接口日志名。 /// 当前生成语句的缩进。 private static void AppendRegistrationLog( StringBuilder builder, string implementationLogName, string handlerInterfaceLogName, string indent) { builder.Append(indent); builder.Append("logger.Debug(\"Registered CQRS handler "); builder.Append(EscapeStringLiteral(implementationLogName)); builder.Append(" as "); builder.Append(EscapeStringLiteral(handlerInterfaceLogName)); builder.AppendLine(".\");"); } private static void AppendOrderedImplementationRegistrations( StringBuilder builder, ImplementationRegistrationSpec registration, int registrationIndex) { var orderedRegistrations = CreateOrderedRegistrations(registration); var implementationVariableName = $"implementationType{registrationIndex}"; AppendImplementationTypeVariable(builder, registration, implementationVariableName); builder.Append(" if ("); builder.Append(implementationVariableName); builder.AppendLine(" is not null)"); builder.AppendLine(" {"); foreach (var orderedRegistration in orderedRegistrations) { AppendOrderedRegistration( builder, registration, orderedRegistration, registrationIndex, implementationVariableName); } builder.AppendLine(" }"); } /// /// 合并直接注册、实现类型反射注册和精确反射注册,并按 handler 接口日志名排序以保持生成输出稳定。 /// /// 单个实现类型聚合后的注册描述。 /// 带有来源类型和原始索引的有序注册列表。 private static List CreateOrderedRegistrations(ImplementationRegistrationSpec registration) { var orderedRegistrations = new List( registration.DirectRegistrations.Length + registration.ReflectedImplementationRegistrations.Length + registration.PreciseReflectedRegistrations.Length); for (var directIndex = 0; directIndex < registration.DirectRegistrations.Length; directIndex++) { orderedRegistrations.Add(new OrderedRegistrationSpec( registration.DirectRegistrations[directIndex].HandlerInterfaceLogName, OrderedRegistrationKind.Direct, directIndex)); } for (var reflectedIndex = 0; reflectedIndex < registration.ReflectedImplementationRegistrations.Length; reflectedIndex++) { orderedRegistrations.Add(new OrderedRegistrationSpec( registration.ReflectedImplementationRegistrations[reflectedIndex].HandlerInterfaceLogName, OrderedRegistrationKind.ReflectedImplementation, reflectedIndex)); } for (var preciseIndex = 0; preciseIndex < registration.PreciseReflectedRegistrations.Length; preciseIndex++) { orderedRegistrations.Add(new OrderedRegistrationSpec( registration.PreciseReflectedRegistrations[preciseIndex].HandlerInterfaceLogName, OrderedRegistrationKind.PreciseReflected, preciseIndex)); } orderedRegistrations.Sort(static (left, right) => StringComparer.Ordinal.Compare(left.HandlerInterfaceLogName, right.HandlerInterfaceLogName)); return orderedRegistrations; } /// /// 发射实现类型变量。公开类型直接使用 typeof,不可直接引用的实现类型则从当前程序集反射解析。 /// /// 生成源码构造器。 /// 单个实现类型聚合后的注册描述。 /// 生成代码中的实现类型变量名。 private static void AppendImplementationTypeVariable( StringBuilder builder, ImplementationRegistrationSpec registration, string implementationVariableName) { if (string.IsNullOrWhiteSpace(registration.ReflectionTypeMetadataName)) { builder.Append(" var "); builder.Append(implementationVariableName); builder.Append(" = typeof("); builder.Append(registration.ImplementationTypeDisplayName); builder.AppendLine(");"); } else { builder.Append(" var "); builder.Append(implementationVariableName); builder.Append(" = registryAssembly.GetType(\""); builder.Append(EscapeStringLiteral(registration.ReflectionTypeMetadataName!)); builder.AppendLine("\", throwOnError: false, ignoreCase: false);"); } } /// /// 根据注册来源发射单条有序注册,确保混合直接和反射路径时仍按 handler 接口名稳定输出。 /// /// 生成源码构造器。 /// 单个实现类型聚合后的注册描述。 /// 带来源类型和原始索引的排序项。 /// 实现类型在整体注册列表中的索引,用于生成稳定变量名。 /// 生成代码中的实现类型变量名。 private static void AppendOrderedRegistration( StringBuilder builder, ImplementationRegistrationSpec registration, OrderedRegistrationSpec orderedRegistration, int registrationIndex, string implementationVariableName) { switch (orderedRegistration.Kind) { case OrderedRegistrationKind.Direct: AppendOrderedDirectRegistration( builder, registration, registration.DirectRegistrations[orderedRegistration.Index], implementationVariableName); break; case OrderedRegistrationKind.ReflectedImplementation: AppendOrderedReflectedImplementationRegistration( builder, registration, registration.ReflectedImplementationRegistrations[orderedRegistration.Index], implementationVariableName); break; case OrderedRegistrationKind.PreciseReflected: AppendOrderedPreciseReflectedRegistration( builder, registration, registration.PreciseReflectedRegistrations[orderedRegistration.Index], registrationIndex, orderedRegistration.Index, implementationVariableName); break; default: throw new InvalidOperationException( $"Unsupported ordered CQRS registration kind {orderedRegistration.Kind}."); } } /// /// 发射实现类型已通过变量解析、handler 接口可直接引用的直接注册语句。 /// /// 生成源码构造器。 /// 单个实现类型聚合后的注册描述。 /// 当前直接注册项。 /// 生成代码中的实现类型变量名。 private static void AppendOrderedDirectRegistration( StringBuilder builder, ImplementationRegistrationSpec registration, HandlerRegistrationSpec directRegistration, string implementationVariableName) { AppendServiceRegistration( builder, $"typeof({directRegistration.HandlerInterfaceDisplayName})", implementationVariableName, " "); AppendRegistrationLog( builder, registration.ImplementationLogName, directRegistration.HandlerInterfaceLogName, " "); } /// /// 发射实现类型需要反射解析、handler 接口可直接引用的注册语句。 /// /// 生成源码构造器。 /// 单个实现类型聚合后的注册描述。 /// 当前实现类型反射注册项。 /// 生成代码中的实现类型变量名。 private static void AppendOrderedReflectedImplementationRegistration( StringBuilder builder, ImplementationRegistrationSpec registration, ReflectedImplementationRegistrationSpec reflectedRegistration, string implementationVariableName) { AppendServiceRegistration( builder, $"typeof({reflectedRegistration.HandlerInterfaceDisplayName})", implementationVariableName, " "); AppendRegistrationLog( builder, registration.ImplementationLogName, reflectedRegistration.HandlerInterfaceLogName, " "); } /// /// 发射 handler 接口需要运行时精确构造的注册语句。 /// /// 生成源码构造器。 /// 单个实现类型聚合后的注册描述。 /// 当前精确反射注册项。 /// 实现类型在整体注册列表中的索引。 /// 当前注册项在原始精确反射注册集合中的索引。 /// 生成代码中的实现类型变量名。 private static void AppendOrderedPreciseReflectedRegistration( StringBuilder builder, ImplementationRegistrationSpec registration, PreciseReflectedRegistrationSpec preciseRegistration, int registrationIndex, int orderedRegistrationIndex, string implementationVariableName) { var registrationVariablePrefix = $"serviceType{registrationIndex}_{orderedRegistrationIndex}"; AppendPreciseReflectedTypeResolution( builder, preciseRegistration.ServiceTypeArguments, registrationVariablePrefix, implementationVariableName, preciseRegistration.OpenHandlerTypeDisplayName, registration.ImplementationLogName, preciseRegistration.HandlerInterfaceLogName, 3); } private static void AppendPreciseReflectedTypeResolution( StringBuilder builder, ImmutableArray serviceTypeArguments, string registrationVariablePrefix, string implementationVariableName, string openHandlerTypeDisplayName, string implementationLogName, string handlerInterfaceLogName, int indentLevel) { var indent = new string(' ', indentLevel * 4); var reflectedArgumentNames = new List(); var resolvedArgumentNames = AppendServiceTypeArgumentResolutions( builder, serviceTypeArguments, registrationVariablePrefix, reflectedArgumentNames, indent); if (reflectedArgumentNames.Count > 0) indent = AppendReflectedArgumentGuardStart(builder, reflectedArgumentNames, indent); AppendClosedGenericServiceTypeCreation( builder, registrationVariablePrefix, openHandlerTypeDisplayName, resolvedArgumentNames, indent); AppendServiceRegistration(builder, registrationVariablePrefix, implementationVariableName, indent); AppendRegistrationLog(builder, implementationLogName, handlerInterfaceLogName, indent); if (reflectedArgumentNames.Count > 0) { builder.Append(new string(' ', indentLevel * 4)); builder.AppendLine("}"); } } /// /// 递归发射每个 handler 泛型实参的运行时类型解析表达式。 /// /// 生成源码构造器。 /// handler 服务类型的运行时泛型实参描述。 /// 当前注册项的稳定变量名前缀。 /// 需要空值检查的反射解析变量集合。 /// 当前生成语句的缩进。 /// 可传给 MakeGenericType 的实参表达式。 private static string[] AppendServiceTypeArgumentResolutions( StringBuilder builder, ImmutableArray serviceTypeArguments, string registrationVariablePrefix, ICollection reflectedArgumentNames, string indent) { var resolvedArgumentNames = new string[serviceTypeArguments.Length]; for (var argumentIndex = 0; argumentIndex < serviceTypeArguments.Length; argumentIndex++) { resolvedArgumentNames[argumentIndex] = AppendRuntimeTypeReferenceResolution( builder, serviceTypeArguments[argumentIndex], $"{registrationVariablePrefix}Argument{argumentIndex}", reflectedArgumentNames, indent); } return resolvedArgumentNames; } /// /// 为运行时反射解析出的泛型实参发射空值保护块,避免生成注册器注册无法完整构造的服务类型。 /// /// 生成源码构造器。 /// 需要参与空值检查的变量名。 /// 保护块开始前的缩进。 /// 保护块内部应使用的下一层缩进。 private static string AppendReflectedArgumentGuardStart( StringBuilder builder, IReadOnlyList reflectedArgumentNames, string indent) { builder.Append(indent); builder.Append("if ("); for (var index = 0; index < reflectedArgumentNames.Count; index++) { if (index > 0) builder.Append(" && "); builder.Append(reflectedArgumentNames[index]); builder.Append(" is not null"); } builder.AppendLine(")"); builder.Append(indent); builder.AppendLine("{"); return $"{indent} "; } /// /// 发射关闭 handler 服务类型的 MakeGenericType 构造语句。 /// /// 生成源码构造器。 /// 生成代码中的服务类型变量名。 /// 开放 handler 接口类型显示名。 /// 已解析的泛型实参表达式。 /// 当前生成语句的缩进。 private static void AppendClosedGenericServiceTypeCreation( StringBuilder builder, string registrationVariablePrefix, string openHandlerTypeDisplayName, IReadOnlyList resolvedArgumentNames, string indent) { builder.Append(indent); builder.Append("var "); builder.Append(registrationVariablePrefix); builder.Append(" = typeof("); builder.Append(openHandlerTypeDisplayName); builder.Append(").MakeGenericType("); for (var index = 0; index < resolvedArgumentNames.Count; index++) { if (index > 0) builder.Append(", "); builder.Append(resolvedArgumentNames[index]); } builder.AppendLine(");"); } private static string AppendRuntimeTypeReferenceResolution( StringBuilder builder, RuntimeTypeReferenceSpec runtimeTypeReference, string variableBaseName, ICollection reflectedArgumentNames, string indent) { if (!string.IsNullOrWhiteSpace(runtimeTypeReference.TypeDisplayName)) return $"typeof({runtimeTypeReference.TypeDisplayName})"; if (runtimeTypeReference.ArrayElementTypeReference is not null) return AppendArrayRuntimeTypeReferenceResolution( builder, runtimeTypeReference, variableBaseName, reflectedArgumentNames, indent); if (runtimeTypeReference.GenericTypeDefinitionReference is not null) return AppendConstructedGenericRuntimeTypeReferenceResolution( builder, runtimeTypeReference, variableBaseName, reflectedArgumentNames, indent); return AppendReflectionRuntimeTypeReferenceResolution( builder, runtimeTypeReference, variableBaseName, reflectedArgumentNames, indent); } /// /// 发射数组类型引用的运行时重建表达式。 /// /// 生成源码构造器。 /// 数组类型引用描述。 /// 用于递归生成变量名的稳定前缀。 /// 需要空值检查的反射解析变量集合。 /// 当前生成语句的缩进。 /// 数组类型表达式。 private static string AppendArrayRuntimeTypeReferenceResolution( StringBuilder builder, RuntimeTypeReferenceSpec runtimeTypeReference, string variableBaseName, ICollection reflectedArgumentNames, string indent) { var elementExpression = AppendRuntimeTypeReferenceResolution( builder, runtimeTypeReference.ArrayElementTypeReference!, $"{variableBaseName}Element", reflectedArgumentNames, indent); return runtimeTypeReference.ArrayRank == 1 ? $"{elementExpression}.MakeArrayType()" : $"{elementExpression}.MakeArrayType({runtimeTypeReference.ArrayRank})"; } /// /// 发射已构造泛型类型引用的运行时重建表达式。 /// /// 生成源码构造器。 /// 已构造泛型类型引用描述。 /// 用于递归生成变量名的稳定前缀。 /// 需要空值检查的反射解析变量集合。 /// 当前生成语句的缩进。 /// 已构造泛型类型表达式。 private static string AppendConstructedGenericRuntimeTypeReferenceResolution( StringBuilder builder, RuntimeTypeReferenceSpec runtimeTypeReference, string variableBaseName, ICollection reflectedArgumentNames, string indent) { var genericTypeDefinitionExpression = AppendRuntimeTypeReferenceResolution( builder, runtimeTypeReference.GenericTypeDefinitionReference!, $"{variableBaseName}GenericDefinition", reflectedArgumentNames, indent); var genericArgumentExpressions = new string[runtimeTypeReference.GenericTypeArguments.Length]; for (var argumentIndex = 0; argumentIndex < runtimeTypeReference.GenericTypeArguments.Length; argumentIndex++) { genericArgumentExpressions[argumentIndex] = AppendRuntimeTypeReferenceResolution( builder, runtimeTypeReference.GenericTypeArguments[argumentIndex], $"{variableBaseName}GenericArgument{argumentIndex}", reflectedArgumentNames, indent); } return $"{genericTypeDefinitionExpression}.MakeGenericType({string.Join(", ", genericArgumentExpressions)})"; } /// /// 发射命名类型的运行时反射查找语句,并返回后续服务类型构造应引用的变量名。 /// /// 生成源码构造器。 /// 反射查找类型引用描述。 /// 生成代码中的反射变量名。 /// 需要空值检查的反射解析变量集合。 /// 当前生成语句的缩进。 /// 生成代码中的反射变量名。 private static string AppendReflectionRuntimeTypeReferenceResolution( StringBuilder builder, RuntimeTypeReferenceSpec runtimeTypeReference, string variableBaseName, ICollection reflectedArgumentNames, string indent) { reflectedArgumentNames.Add(variableBaseName); builder.Append(indent); builder.Append("var "); builder.Append(variableBaseName); if (string.IsNullOrWhiteSpace(runtimeTypeReference.ReflectionAssemblyName)) { builder.Append(" = registryAssembly.GetType(\""); builder.Append(EscapeStringLiteral(runtimeTypeReference.ReflectionTypeMetadataName!)); builder.AppendLine("\", throwOnError: false, ignoreCase: false);"); } else { builder.Append(" = ResolveReferencedAssemblyType(\""); builder.Append(EscapeStringLiteral(runtimeTypeReference.ReflectionAssemblyName!)); builder.Append("\", \""); builder.Append(EscapeStringLiteral(runtimeTypeReference.ReflectionTypeMetadataName!)); builder.AppendLine("\");"); } return variableBaseName; } private static void AppendReflectionHelpers(StringBuilder builder) { builder.AppendLine( " private static global::System.Type? ResolveReferencedAssemblyType(string assemblyIdentity, string typeMetadataName)"); builder.AppendLine(" {"); builder.AppendLine(" var assembly = ResolveReferencedAssembly(assemblyIdentity);"); builder.AppendLine( " return assembly?.GetType(typeMetadataName, throwOnError: false, ignoreCase: false);"); builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine( " private static global::System.Reflection.Assembly? ResolveReferencedAssembly(string assemblyIdentity)"); builder.AppendLine(" {"); builder.AppendLine(" global::System.Reflection.AssemblyName targetAssemblyName;"); builder.AppendLine(" try"); builder.AppendLine(" {"); builder.AppendLine( " targetAssemblyName = new global::System.Reflection.AssemblyName(assemblyIdentity);"); builder.AppendLine(" }"); builder.AppendLine(" catch"); builder.AppendLine(" {"); builder.AppendLine(" return null;"); builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine( " foreach (var assembly in global::System.AppDomain.CurrentDomain.GetAssemblies())"); builder.AppendLine(" {"); builder.AppendLine( " if (global::System.Reflection.AssemblyName.ReferenceMatchesDefinition(targetAssemblyName, assembly.GetName()))"); builder.AppendLine(" return assembly;"); builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine(" try"); builder.AppendLine(" {"); builder.AppendLine( " return global::System.Reflection.Assembly.Load(targetAssemblyName);"); builder.AppendLine(" }"); builder.AppendLine(" catch"); builder.AppendLine(" {"); builder.AppendLine(" return null;"); builder.AppendLine(" }"); builder.AppendLine(" }"); } private static string EscapeStringLiteral(string value) { return value.Replace("\\", "\\\\") .Replace("\"", "\\\"") .Replace("\n", "\\n") .Replace("\r", "\\r"); } }