I have a Serializer/Deserializer that use a references PreserveReferencesHandling = PreserveReferencesHandling.All
.
The issue, is that I have circular references.
Here is a very simple example.
class Node
{
public Node(object value)
{
Value = value;
}
public object Value { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
}
My test scenario is:
var obj = new Node("o")
{
Left = new Node("oL"),
Right = new Node("oR")
};
obj.Right.Right = obj; // Circular reference!
When I deserialize, i have the following IReferenceResolver
private class InternalReferenceResolver : IReferenceResolver
{
private readonly Deserializer _par;
public InternalReferenceResolver(Deserializer par)
{
_par = par;
}
public object ResolveReference(object context, string reference)
{
object refObject;
if (!_par._processed.TryGetValue(reference, out refObject))
{
refObject = _par.DeserializeObject(reference);
}
return refObject;
}
public string GetReference(object context, object value)
{
throw new NotSupportedException("Only for Serialization");
}
public bool IsReferenced(object context, object value)
{
return false;
}
public void AddReference(object context, string reference, object value)
{
_par._processed.Add(reference, value);
}
}
As you can see, when JSON.NET inform me of a new ref->object (via AddReference()
) I add it to a dictionary.
When JSON.NET request an object for a specific reference (via ResolveReference()
) I recurse, and deserialize that reference.
The issue is, JSON.NET calls ResolveReference()
for each of the object references, before it calls it's AddReference()
.
I would expect the flow of Deserialization to be:
- Identify Object Type
- Construct the object
- AddReference(id, newObj)
- Resolve References + Populate Properties
What I see happens is:
- Identify Object Type
- Resolve References
- Construct the object
- AddReference(id, newObj)
- Populate Properties
My Questions:
Why is it made the latter, am i missing something with my suggested flow?
how can I overcome this issue, having a "Bare" object just for referencing and only then actually resolve the references ?