Develop/aot il2026#247
Conversation
Enables IsAotCompatible on net8.0 and promotes IL2026/IL2104/IL3050/IL3053 to errors. Build fails today on JsonSerializer.Deserialize and the enum JsonConverterFactory call sites — the exact surface a source-generated JsonSerializerContext fix needs to cover. Intentionally not for merge: this branch is a living acceptance test for the eventual AOT fix.
…apsAPIGenericEngine class cleaned
|
Hi, thanks for your contribution! I'm planning to drop older TF soon (#242), so I'm thinking to delay your PR till this is done so it will be simpler and we won't need the precompile rules (#if NET5_0_OR_GREATER) |
|
You have many files with just spaces/tabs diff (for example GoogleMapsApi/QueryStringParametersList.cs), can you remove them from the PR? |
|
Hi, |
|
Hi, I just realized that maintaining this will be complicated, because after each new class or enum addition, it will be necessary to add the type to both GoogleMapsJsonSerializerContext and EnumMemberJsonConverterFactory. That's why I created two T4 template generators: AOT_T4_Generator |
|
I've released v2. We can have a look now. Would it be easier for you to resolve conflict or redo it on master branch? |
|
Yes i can, no problem i will redo it. |
|
Thanks — happy to take the AOT work on master. One ask on direction before you redo it: I'd rather not bring in the T4 generators. The maintenance burden they solve is real, but I think we can design it away instead of code-generating around it:
Net result: no build-time tooling, nothing generated/checked-in to go stale, and both registries the templates exist to maintain are gone. If we ever genuinely outgrow the manual Also note the TFMs are now Sound good? |
|
Okay, sounds good to me. |
|
I tried to use JsonSerializable but it doesn't seems to go welll. You can take a look at this branch : develop/AOT_without_T4 It is not possible to apply JsonSerializable directly on entity classes. The JsonSerializable attributes must be placed on a class that derives from JsonSerializerContext (for example GoogleMapsJsonSerializerContext) so the System.Text.Json source generator can produce the required JsonTypeInfo objects. Applying the attribute to entities will not trigger the generator. |
|
Thanks for trying it out — I think there's a mix-up between two different attributes here, and it's my fault for putting both points in one comment. Let me untangle them:
So the change is: // On each enum:
[JsonConverter(typeof(EnumMemberJsonConverter<TravelMode>))]
public enum TravelMode
{
[EnumMember(Value = "driving")]
Driving,
// ...
}// And delete EnumMemberJsonConverterFactory entirely — no factory, no MakeGenericType,
// no central whitelist to keep in sync. That removes both T4 templates' reason to exist
// and makes AotCompatibleTests optional.The On Give that a shot and let me know if the analyzers still complain — happy to look at a draft branch. |
|
Hi @IchiSamaFR — no rush at all, just checking in on this one. I think we'd untangled the last sticking point: the enum fix is That same Are you still up for reworking it in that direction on master? Totally fine either way — if you're busy I'm happy to pick up a draft from here and credit you, just let me know. Thanks again for digging into this! |
|
Hello, Unfortunatly I had a priority project, i will not be able to work on it for 2 weekss Except using T4 Generator, which is pretty annoying to generate each time, there is a new possibility, Source Generators |
Summary
Migrate JSON deserialization to a source-generated
JsonSerializerContextto enable AOT/trim compatibility onnet8.0and fix IL2026/IL3050 warnings. The reflection-basedJsonSerializerConfigurationhas been removed and replaced with a singleGoogleMapsJsonSerializerContextused across all target frameworks.A further improvement would be to introduce a T4 template (
.ttfile) that scans the project at code-generation time, discovers everyenumtype in theGoogleMapsApiassembly, and automatically regenerates theConvertersdictionary insideEnumMemberJsonConverterFactory. This would guarantee that no enum converter is ever accidentally omitted when a new enum is added, removing the current need for manual registration and eliminating the associated runtimeNotSupportedExceptionrisk on AOT targets.Related issue
Fixes #195 — AOT/trim incompatibility with reflection-based
JsonSerializercalls.Changes
GoogleMapsJsonSerializerContext— a[JsonSerializable]-annotated partial context registering all response types, with[JsonSourceGenerationOptions]declaring custom converters (EnumMemberJsonConverterFactory,PriceLevelJsonConverter,OverviewPolylineJsonConverter,DurationJsonConverter<T>).JsonSerializerConfiguration(reflection-based options builder) and replaced with context-driven deserialization inMapsAPIGenericEngine.[JsonConverter]attributes directly on entity properties (Leg,Step,Route,TransitDetails,Element,Geometry) so the source generator picks up the custom converters at compile time.EnumMemberJsonConverterFactoryto its own file; underNET5_0_OR_GREATERit uses a static whitelist of known enum types instead ofMakeGenericTypeto stay AOT-safe.[DynamicallyAccessedMembers]annotation toDurationJsonConverter<T>andEnumMemberJsonConverter<TEnum>to suppress IL2026/IL3050 on supported targets.JsonSerializerOptions _optionssetup with a sharedJsonMultitargetsutility that selects betweenJsonTypeInfo<T>and options-based deserialization for older targets.SYSLIB1031warnings by giving each[JsonSerializable]entry a uniqueTypeInfoPropertyNamefor ambiguous short names (Status,Result,Geometry, etc.).Test plan
JsonConverterTests,EnhancedJsonConverterTests,EdgeCaseAndErrorHandlingTests,NullableReferenceTypesCompatibilityTests) updated to useJsonMultitargetsand still pass.AotCompatibleTestsadded to ensure all enums are declared into theEnumMemberJsonConverterFactory.net8.0(AOT analyzers enabled),net6.0,netstandard2.0,net481,net462.net8.0target.Checklist
dotnet formathas been run.dotnet testpasses locally (with a validGOOGLE_API_KEYfor integration tests).