-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Add specification for ReferenceHandling #354
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
Conversation
|
I had already provided most of the feedback here: jozkee/corefx#1 I will review the revisions made to this doc soon. |
Add note about immutable types
ahsonkhan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bunch of nits and re-wording suggestions. Otherwise, looks great!
| 3. While Immutable types and `System.Array`s can be Serialized with Preserve semantics, they will not be supported when trying to Deserialize them as a reference; those types are created with the help of an internal converter, and they are not parsed until the entire block of JSON finishes, nested reference to these types is impossible to identify, unless you re-scan the resulting object, which is too expensive. | ||
| 4. Value types, such as structs that contain preserve semantics, will not be supported when Deserialized as well; this is because the serializer will never signal a reference object to those types, doing such thing implies boxing of value types. | ||
| 5. Additional features, such as Converter support, `ReferenceResolver`, `JsonPropertyAttribute.IsReference` and `JsonPropertyAttribute.ReferenceLoopHandling`, that build on top of `ReferenceLoopHandling` and `PreserveReferencesHandling` were considered but they can be added in the future based on customer requests. | ||
| 6. We are still looking for evidence that backs up supporting `ReferenceHandling.Ignore`, this option will not ship if said evidence is not found. No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 6. We are still looking for evidence that backs up supporting `ReferenceHandling.Ignore`, this option will not ship if said evidence is not found. | |
| 6. We are still looking for evidence that backs up supporting `ReferenceHandling.Ignore`. This option will not ship if said evidence is not found. |
Co-Authored-By: Ahson Khan <[email protected]>
Co-Authored-By: Ahson Khan <[email protected]>
Co-Authored-By: Ahson Khan <[email protected]>
…$values Co-Authored-By: Ahson Khan <[email protected]>
|
Hello @ahsonkhan! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
|
|
||
| * Expose the `ReferenceResolver` in `Converters` to have access to the map of references. | ||
|
|
||
| * Create `JsonReferenceHandlingAttribute` to enable annotating properties and classes with their own isolated `ReferenceHandling` behavior (I am deferring this feature because the constant checking for attributes was causing too much perf overhead on the main path, but maybe we can try moving the attribute check to the warm-up method to reduce the runtime increase). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - in the future, checking the attributes once during warm-up is the way to go.
| ReferenceHandling = ReferenceHandling.Preserve | ||
| }; | ||
|
|
||
| //Throw JsonException - PropertyName cannot start with '$' when Preserve References is enabled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| //Throw JsonException - PropertyName cannot start with '$' when Preserve References is enabled. | |
| // Throw JsonException - PropertyName cannot start with '$' when Preserve References is enabled. |
| //Throw JsonException - PropertyName cannot start with '$' when Preserve References is enabled. | ||
| string json = JsonSerializer.Serialize(root, opts); | ||
|
|
||
| //Also throws the same exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| //Also throws the same exception. | |
| // Throws the same exception as above. |
|
|
||
| **Reference loops**: Also referred as circular references, loops occur when a property of a .NET object refers to the object itself, either directly (a -> a) or indirectly (a -> b -> a). They also occur when the element of an array refers to the array itself (arr[0] -> arr). Multiple occurrences of the same reference do not imply a cycle. | ||
|
|
||
| **Preserve duplicated references**: Semantically represent objects and/or arrays that have been previously written, with a reference to them when found again in the object graph (using reference equality for comparison). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provide the definition for deserialization?
|
|
||
| **Metadata**: Extra properties on JSON objects and/or arrays (that may change their schema) to enable reference preservation when round-tripping. These additional properties are only meant to be understood by the `JsonSerializer`. | ||
|
|
||
| # Motivation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also address the motivation for deserialization - to preserve references.
| ``` | ||
| See also the [internal implementation details](https://gist.github.com/Jozkee/b0922ef609f7a942f00ac2c93a976ff1). | ||
|
|
||
| ## In depth |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this title is a bit confusing - my mind first went to serialization depth (maybe it's just me)
Consider "A closer look Default, Preserve, and Ignore reference handling options" or something...
|
|
||
| * `$.*` **Valid** | ||
|
|
||
| Note: For Dictionary keys on serialize, should we allow serializing keys `$id`, `$ref` and `$values`? If we allow it, then there is a potential round-tripping issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to the few questions sprinkled around the doc in their respective discussion contexts, I'd add an open questions recap at the end of the doc so we can recall them.
| Note: By the same principle, `Newtonsoft.Json` does not support parsing JSON arrays into immutables as well. | ||
| Note 2: When using immutable types and `ReferenceHandling.Preserve`, you will not be able to generate payloads that are capables of round-tripping. | ||
|
|
||
| * **Immutable types**: i.e: `ImmutableList` and `ImmutableDictionary` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * **Immutable types**: i.e: `ImmutableList` and `ImmutableDictionary` | |
| * **Immutable types**: e.g. `ImmutableList` and `ImmutableDictionary` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always though i.e. stands for "in example".
| * **Immutable types**: i.e: `ImmutableList` and `ImmutableDictionary` | ||
| * **System.Array**: i.e: `Array<T>` and `T[]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are collections that don't implement IList/IDictionary, but don't use internal converters--like Stack<T> and HashSet<T>--supported for this feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, all collections, as long as they don't rely on a converter, should be compatible with the feature.
|
@jozkee, what's the status of this PR? |
|
This has been approved, marked as auto-merge, and open for months. I'm going to merge it. If you need to make more changes to the doc, please open a new PR. Thanks. |
No description provided.