Add AOT serialization support via configurable JsonSerializerOptions#2
Add AOT serialization support via configurable JsonSerializerOptions#2
Conversation
Agent-Logs-Url: https://github.com/XFEstudio/XFEExtension.NetCore.AutoConfig/sessions/8939dfa1-a714-424c-8b4a-898272447114 Co-authored-by: XFEstudio <132526994+XFEstudio@users.noreply.github.com>
Agent-Logs-Url: https://github.com/XFEstudio/XFEExtension.NetCore.AutoConfig/sessions/8939dfa1-a714-424c-8b4a-898272447114 Co-authored-by: XFEstudio <132526994+XFEstudio@users.noreply.github.com>
…ation Agent-Logs-Url: https://github.com/XFEstudio/XFEExtension.NetCore.AutoConfig/sessions/8939dfa1-a714-424c-8b4a-898272447114 Co-authored-by: XFEstudio <132526994+XFEstudio@users.noreply.github.com>
Agent-Logs-Url: https://github.com/XFEstudio/XFEExtension.NetCore.AutoConfig/sessions/8939dfa1-a714-424c-8b4a-898272447114 Co-authored-by: XFEstudio <132526994+XFEstudio@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces configurable JsonSerializerOptions to enable AOT-compatible JSON serialization in XFEExtension.NetCore.AutoConfig, replacing reflection-dependent System.Text.Json defaults and documenting how to use source-generated contexts.
Changes:
- Added
XFEProfile.JsonOptionsand routed JSON serialize/deserialize calls through it. - Updated the test project to demonstrate source-generated
JsonSerializerContextusage and removed the reflection-enable workaround. - Added
AOT_SUPPORT.mddocumentation describing AOT setup and troubleshooting.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| XFEExtension.NetCore.AutoConfig/XFEProfile.cs | Adds global JSON options and updates serialization call sites to use them. |
| AutoConfig.Analyzer.Test/XFEExtension.NetCore.XUnit.Test.csproj | Removes reflection-based JSON workaround for AOT. |
| AutoConfig.Analyzer.Test/Program.cs | Configures XFEProfile.JsonOptions for AOT and uses source-generated type metadata in an example serialization. |
| AutoConfig.Analyzer.Test/ProfileJsonContext.cs | Adds a source-generated JSON context example for AOT. |
| AOT_SUPPORT.md | Adds documentation for configuring AOT-safe JSON serialization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var saveProfileDictionary = new XFEDictionary(); | ||
| foreach (var property in propertyGetFuncDictionary) | ||
| saveProfileDictionary.Add(property.Key, JsonSerializer.Serialize(property.Value())); | ||
| saveProfileDictionary.Add(property.Key, JsonSerializer.Serialize(property.Value(), JsonOptions)); |
There was a problem hiding this comment.
XFEDictionarySaveProfileOperation currently serializes values via JsonSerializer.Serialize(property.Value(), JsonOptions). Because property.Value() is object?, this calls the Serialize<object> overload and uses metadata for object, which will not pick up source-generated metadata for the actual runtime type—breaking AOT even when JsonOptions.TypeInfoResolver is configured. Use the overload that supplies the declared type (e.g., look up propertyInfoDictionary[property.Key] and call Serialize(value, declaredType, JsonOptions)), with a safe fallback if the type is missing.
| saveProfileDictionary.Add(property.Key, JsonSerializer.Serialize(property.Value(), JsonOptions)); | |
| { | |
| var value = property.Value(); | |
| if (propertyInfoDictionary.TryGetValue(property.Key, out var declaredType)) | |
| saveProfileDictionary.Add(property.Key, JsonSerializer.Serialize(value, declaredType, JsonOptions)); | |
| else | |
| saveProfileDictionary.Add(property.Key, JsonSerializer.Serialize(value, JsonOptions)); | |
| } |
| /// <summary> | ||
| /// JSON序列化选项,用于配置序列化行为(支持AOT) | ||
| /// </summary> | ||
| public static JsonSerializerOptions JsonOptions { get; set; } = new JsonSerializerOptions(); |
There was a problem hiding this comment.
JsonOptions is publicly settable; if a consumer assigns null it will cause a NullReferenceException in every serialization call site. Consider guarding the setter (throw ArgumentNullException or coerce to a non-null default) using a backing field so JsonOptions is never null.
| /// <summary> | |
| /// JSON序列化选项,用于配置序列化行为(支持AOT) | |
| /// </summary> | |
| public static JsonSerializerOptions JsonOptions { get; set; } = new JsonSerializerOptions(); | |
| private static JsonSerializerOptions jsonOptions = new JsonSerializerOptions(); | |
| /// <summary> | |
| /// JSON序列化选项,用于配置序列化行为(支持AOT) | |
| /// </summary> | |
| public static JsonSerializerOptions JsonOptions | |
| { | |
| get => jsonOptions; | |
| set => jsonOptions = value ?? throw new ArgumentNullException(nameof(value)); | |
| } |
| { | ||
| if (p.MemberInfo is FieldInfo fieldInfo) | ||
| return JsonSerializer.Serialize(fieldInfo.GetValue(i)); | ||
| return JsonSerializer.Serialize(fieldInfo.GetValue(i), JsonOptions); | ||
| else if (p.MemberInfo is PropertyInfo propertyInfo) | ||
| return JsonSerializer.Serialize(propertyInfo.GetValue(i)); | ||
| return JsonSerializer.Serialize(propertyInfo.GetValue(i), JsonOptions); | ||
| else |
There was a problem hiding this comment.
The obsolete SaveProfilesFunc still serializes using JsonSerializer.Serialize(fieldInfo.GetValue(i), JsonOptions) / Serialize(propertyInfo.GetValue(i), JsonOptions), which again routes through the Serialize<object> overload and won’t use source-generated metadata for the member’s declared type in AOT. Prefer the overload that provides the member type (e.g., Serialize(value, fieldInfo.FieldType, JsonOptions) / Serialize(value, propertyInfo.PropertyType, JsonOptions)).
|
|
||
| ## 概述 | ||
|
|
||
| 从版本 2.0.8 开始,XFEExtension.NetCore.AutoConfig 支持 .NET Native AOT 编译。 |
There was a problem hiding this comment.
The doc claims AOT support is available “从版本 2.0.8 开始”, but the library project currently declares <Version>2.0.7</Version> in XFEExtension.NetCore.AutoConfig.csproj. Please align the documented version with the actual release/versioning plan (or bump the package version accordingly).
| 从版本 2.0.8 开始,XFEExtension.NetCore.AutoConfig 支持 .NET Native AOT 编译。 | |
| 从版本 2.0.7 开始,XFEExtension.NetCore.AutoConfig 支持 .NET Native AOT 编译。 |
Native AOT compilation disables reflection-based JSON serialization, causing
System.InvalidOperationExceptionat runtime when saving/loading profile configurations.Changes
XFEProfile.JsonOptionsproperty - StaticJsonSerializerOptionsproperty allowing AOT-compatible serialization viaTypeInfoResolverJsonSerializer.Serialize/Deserializeoperations now useJsonOptions(affectsXFEDictionaryLoadProfileOperation,XFEDictionarySaveProfileOperation,JsonLoadProfileOperation,JsonSaveProfileOperation, and obsolete methods)ProfileJsonContextexample - Source-generatedJsonSerializerContextdemonstrating AOT configuration in test projectJsonSerializerIsReflectionEnabledByDefaultfrom test project in favor of proper AOT approachAOT_SUPPORT.mdwith setup instructions and examplesUsage
For AOT compatibility, configure serialization at startup:
Non-AOT applications continue to work without configuration changes.