-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: JsonSourceGenerationOptions should support ReferenceHandler #107597
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis |
The namespace System.Text.Json.Serialization;
public enum JsonKnownReferenceHandler
{
IgnoreCycles = 1,
Preserve = 2,
Unspecified = 0,
}
public partial class JsonSourceGenerationOptionsAttribute
{
public JsonKnownReferenceHandler ReferenceHandler { get; set; }
} Would that cover your use case? |
User-defined handler type could be specified with BTW, is it actionable to support user-defined naming style in SG mode? Since generated metadata needs to materialize the type info, the serialized field names can no longer be generated as constants. |
The implementation types are not public I'm afraid: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.referencehandler?view=net-8.0
I'm not sure I follow the question, could you give an example? |
@eiriktsarpalis Just wondering if this can be prioritized. I'm trying to switch to AOT, but definition: usage: |
For this code snippet: public class MyType
{
public string SomeProperty { get; set; }
}
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower)]
[JsonSerializable(typeof(MyType))]
public partial class MyContext : JsonSerializerContext { } Currently there will be It was desired because snake case wasn't even a built-in naming policy in previous versions. |
It's still possible to use reference handling with the source generator, but it requires slightly more boilerplate. This works with Native AOT: JsonSerializer.Serialize(new MyPoco("John", 30), MyContext.Custom.MyPoco); // {"$id":"1","Name":"John","Age":30}
record MyPoco(string Name, int Age);
[JsonSerializable(typeof(MyPoco))]
partial class MyContext : JsonSerializerContext
{
public static MyContext Custom { get; } = new(new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.Preserve,
WriteIndented = true,
});
}
I see, the naming policy is run at compile time as a performance optimization for the fast-path serializer but it doesn't need to do so. Assuming we had an API where either the naming policies or reference handlers were exposed as named types (they are not today) we might conceivably have an API that lets users nominate their own implementations (as is the case with the |
Thanks for the code example. I went with your recommendation to unblock myself for now. It'd still be great to override the default behavior in the future (through |
namespace System.Text.Json.Serialization;
public enum KnownReferenceHandler // Naming follows the ReferenceHandler type which misses a Json prefix
{
IgnoreCycles = 1,
Preserve = 2,
Unspecified = 0,
}
public partial class JsonSourceGenerationOptionsAttribute
{
public KnownReferenceHandler ReferenceHandler { get; set; }
} |
I created a PR with the approved api shape, but adding this option seems like it's setting a precedent to keep adding more options to JsonSourceGenerationOptionsAttribute. That approach makes sense for
The reference handler also has codegen, but it's very minor - specifically it is just used to construct the object initializer for the default options:
The default option doesn't need to be a compile time constant - it just needs to be instantiated before the context singleton is created. So an alternative to the approved API you could consider is to provide an extension point to allow the user to specify their default options. I'm sure there are a few options to do this, but maybe something like this would work (using static partial here since default options and singleton are static):
The idea being that the user can implement this if they want by mutating the default options parameter and we use the mutated value to create the singleton context. |
Don't the existing APIs of |
Background and motivation
Provide a way to specify a reference handler using compile-time configuration.
API Proposal
The
ReferenceHandler
type is a class and therefore it cannot be specified in literal annotations. If we wanted to add support for that it would require introducing a proxy enum type, in the style ofJsonKnownEnumPolicy
. However that would leave out support for user-defined reference handlers in case that matters:API Usage
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: