-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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]: Source Generate System.Text.Json Context Class #80220
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsBackground and motivationI am currently using C# to create small self-contained applications with NativeAOT, many of which require JSON serialization for either saving application settings or receiving data from remote APIs. As NativeAOT does not (currently) work with reflection, I have been exclusively using source-generated serializers which require a bit more code to get working, in the form of the serialization context (which can become increasingly hard to maintain as an application grows, see #73297). While I'm not too familiar with the way the source-generator works behind the scenes or if this would even be possible with the current situation, simply comparing the flow of serializing an object to json to other AOT languages such as Dart, Kotlin/Native, and Swift there seems to be a lot less friction in those languages as compared to .NET. I was wondering if there could be a way for the source generator to write this class instead of the user. API ProposalIdeally the source generator would create the context class when generating the rest of the required code, and store it in a standard location for the (Unfortunately I am not experienced enough to determine how this would take form in framework code) API UsageIf it's possible, having a default internal context for (example code modified from learn.microsoft.com) jsonString = JsonSerializer.Serialize(
weatherForecast, typeof(WeatherForecast));
[JsonSerializable]
class WeatherForecast {
[...]
} Alternative DesignsCurrently reflection-based APIs use the same method signature as the proposal above, so to explicitly specify source generation as the method to use could help resolve this conflict. sourceGenOptions = new JsonSerializerOptions
{
SerializerMode = JsonSerializerMode.SourceGen
};
jsonString = JsonSerializer.Serialize(
weatherForecast, typeof(WeatherForecast), sourceGenOptions); or jsonString = JsonSerializer.Serialize(
weatherForecast, typeof(WeatherForecast), SourceGen = true); RisksThis reduces flexibility, as many options that would traditionally be passed through the context, and is therefore not intended to replace the existing method, but provide a syntactically simpler alternative for small applications.
|
Strictly speaking it's likely possible. The problem is that if you put such a context in a "well known" location you - and every library you might reference - can have only one copy, which would be a fun way to cause waves of breaking changes throughout the ecosystem. You could instead segment it by having a context object for each namespace an object is from, but namespaces can have objects from multiple packages, so it's still possible to cause breaking waves, plus all the fun of having multiple contexts that you're trying to juggle. So the most realistic version is the instance listed in that other issue.
This means it's extremely unlikely to happen.
Source generators, as a feature, run solely at compile time, so you couldn't make it a runtime option. They're also strictly additive, so you can't replace those calls at compile time with something else either. |
Source Generators do not run ordered at the moment, it is afaik not possible to have one source generator depend on the output of another one. |
Yeah we could expand on the current gesture for the source generator by allowing the This pattern was discussed in the early period of the JSON source generator design and punted since it wasn't necessary for v1. With strong enough indication that this is a widely-felt problem we could come up with a solution here. |
On top of what @Clockwork-Muse said - I'm not sure how would we handle different options for those types. We definitely can't generate code for every possible option |
Perhaps we could pass an instance of
|
Attribute arguments must be constants, so that version doesn't work. Probably, you'd want to have a factory interface you were required to implement that would return the option, which you could specify via type. |
Background and motivation
I am currently using C# to create small self-contained applications with NativeAOT, many of which require JSON serialization for either saving application settings or receiving data from remote APIs. As NativeAOT does not (currently) work with reflection, I have been exclusively using source-generated serializers which require a bit more code to get working, in the form of the serialization context (which can become increasingly hard to maintain as an application grows, see #73297). While I'm not too familiar with the way the source-generator works behind the scenes or if this would even be possible with the current situation, simply comparing the flow of serializing an object to json to other AOT languages such as Dart, Kotlin/Native, and Swift there seems to be a lot less friction in those languages as compared to .NET. I was wondering if there could be a way for the source generator to write this class instead of the user.
API Proposal
Ideally the source generator would create the context class when generating the rest of the required code, and store it in a standard location for the
Serialize
andDeserialize
methods to search unless an existing context class is provided.(Unfortunately I am not experienced enough to determine how this would take form in framework code)
API Usage
If it's possible, having a default internal context for
JsonSerializer
to search would simplify the calls toSerialize
/Deserialize
, as the programmer no longer has to write(example code modified from learn.microsoft.com)
Alternative Designs
Currently reflection-based APIs use the same method signature as the proposal above, so to explicitly specify source generation as the method to use could help resolve this conflict.
or
Risks
This reduces flexibility, as many options that would traditionally be passed through the context, and is therefore not intended to replace the existing method, but provide a syntactically simpler alternative for small applications.
These changes would be breaking, and require refactoring existing Serialization code. Provided the current method of writing a custom context class remains, it shouldn't cause too much breakage for current code-bases.
The text was updated successfully, but these errors were encountered: