Annotate Core/IoC reflective surface for AOT (closes #253)#258
Merged
Conversation
Second AOT-pillar slice (#213). 30 IL warnings per TFM across 7 files in Core/IoC → 0, plus matching propagation to AssemblyScanner / ScanningExploder / ServiceCollectionExtensions.Scan to keep IL2026 quiet across the public convention-registration surface. Convention-scanning is fundamentally trim-hostile: TypeSet enumerates types from loaded assemblies, conventions register types by naming / interface patterns, and ServiceDescriptors are constructed from runtime- discovered Types. AOT-publishing apps should either avoid convention-based registration entirely (use explicit services.AddSingleton<T, TImpl>()) or substitute a source-generated registration manifest. Public surface annotated IRegistrationConvention.ScanTypes — [RUC] + [RDC] ServiceCollectionExtensions.Scan(IServiceCollection, Action<IAssemblyScanner>) — [RUC] + [RDC] ServiceCollectionExtensions.AddType(IServiceCollection, Type, Type, ServiceLifetime) — [DAM(PublicConstructors)] on implementationType AssemblyScanner.ApplyRegistrations — [RUC] + [RDC] FindAllTypesFilter.IRegistrationConvention.ScanTypes — [RUC] + [RDC] (matches interface) Implementations annotated (match interface) DefaultConventionScanner.ScanTypes — [RUC] + [RDC] FirstInterfaceConvention.ScanTypes — [RUC] + [RDC] ImplementationMap.ScanTypes — [RUC] + [RDC] GenericConnectionScanner.ScanTypes — [RUC] + [RDC] Internal helpers annotated TypeExtensions.CanBeCreated(this Type) — [DAM(PublicConstructors)] TypeExtensions.FindFirstInterfaceThatCloses(this Type, Type) — [DAM(Interfaces)] TypeExtensions.FindInterfacesThatClose(this Type, Type) — [DAM(Interfaces)] Internal propagation ScanningExploder.Explode + ExplodeSynchronously — [RUC] + [RDC] Suppressed with justification DefaultConventionScanner.FindServiceType — IL2070 on GetInterfaces() GenericConnectionScanner.addConcretionsThatCouldBeClosed — IL2055/IL2067/IL3050 on MakeGenericType + ServiceDescriptor FindAllTypesFilter.Matches + determineLeastSpecificButValidType — IL2070/IL2067 TypeExtensions.rawFindInterfacesThatCloses — IL2070 on recursive BaseType walk Effect on the punch list JasperFx total per TFM: 188 → 158 (-30, Core/IoC slice) Remaining slices: #252 Core/Reflection 64 #254 ServiceContainer.cs 16 (PR #256 in flight) #255 CodeGeneration/Services 22 (PR #257 in flight) Core/TypeScanning 10 CodeGeneration/Snapshots 8 CodeGeneration/GeneratedType.cs 8 JasperFxOptions.cs 6 misc tail ~24 Verification CoreTests 407/407 pass on net9.0 + net10.0 SmokeTestAot build clean, exits 0 Closes #253.
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second AOT-pillar slice (#213) — closes #253.
30 IL warnings per TFM across 7 files in
Core/IoC→ 0, plus matching propagation toAssemblyScanner/ScanningExploder/ServiceCollectionExtensions.Scanto keep IL2026 quiet across the public convention-registration surface.Why annotate (not just suppress)
Convention-scanning is fundamentally trim-hostile:
TypeSetenumerates types from loaded assemblies, conventions register types by naming / interface patterns, andServiceDescriptors are constructed from runtime-discoveredTypes. AOT-publishing apps should either avoid convention-based registration entirely (use explicitservices.AddSingleton<TService, TImpl>()) or substitute a source-generated registration manifest.Public surface annotated
IRegistrationConvention.ScanTypes[RUC]+[RDC]ServiceCollectionExtensions.Scan(IServiceCollection, Action<IAssemblyScanner>)[RUC]+[RDC]ServiceCollectionExtensions.AddType(IServiceCollection, Type, Type, ServiceLifetime)[DAM(PublicConstructors)]onimplementationTypeAssemblyScanner.ApplyRegistrations[RUC]+[RDC]FindAllTypesFilter.IRegistrationConvention.ScanTypes[RUC]+[RDC](matches interface)Implementations annotated (match interface)
DefaultConventionScanner.ScanTypes,FirstInterfaceConvention.ScanTypes,ImplementationMap.ScanTypes,GenericConnectionScanner.ScanTypes— all carry the matching[RequiresUnreferencedCode]+[RequiresDynamicCode].Internal helpers annotated
TypeExtensions.CanBeCreated(this Type)[DAM(PublicConstructors)]TypeExtensions.FindFirstInterfaceThatCloses(this Type, Type)[DAM(Interfaces)]TypeExtensions.FindInterfacesThatClose(this Type, Type)[DAM(Interfaces)]Internal propagation
ScanningExploder.Explode+ExplodeSynchronouslyannotated with[RUC]+[RDC]to keep the convention-scan dispatch site quiet.Suppressed with justification
DefaultConventionScanner.FindServiceTypeGetInterfaces(). Reached only fromScanTypeswhich is annotated; user invariant for convention scanning is that registered types' interfaces survive trimming.GenericConnectionScanner.addConcretionsThatCouldBeClosedMakeGenericType+ServiceDescriptorctor. The caller (ScanTypes) is annotated[RDC].FindAllTypesFilter.Matches+determineLeastSpecificButValidTypetype.GetConstructors()+FindFirstInterfaceThatCloses. Convention-scan discovery surface.TypeExtensions.rawFindInterfacesThatClosesBaseTypewalk. Trim impact bounded by the entry-point[DAM(Interfaces)].Effect on the punch list
Remaining slices: #252 Core/Reflection (64), #254 ServiceContainer.cs (16, PR #256 in flight), #255 CodeGeneration/Services (22, PR #257 in flight), plus smaller tails.
Verification
CoreTests— 407/407 pass on net9.0 + net10.0SmokeTestAot— build clean, exits 0Closes #253.
🤖 Generated with Claude Code