| File: System\Text\Json\Serialization\PreserveReferenceResolver.cs | Web Access |
| Project: src\runtime\src\libraries\System.Text.Json\src\System.Text.Json.csproj (System.Text.Json) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Diagnostics; namespace System.Text.Json.Serialization { /// <summary> /// The default ReferenceResolver implementation to handle duplicate object references. /// </summary> internal sealed class PreserveReferenceResolver : ReferenceResolver { private uint _referenceCount; private readonly Dictionary<string, object>? _referenceIdToObjectMap; private readonly Dictionary<object, string>? _objectToReferenceIdMap; public PreserveReferenceResolver(bool writing) { if (writing) { // Comparer used here does a reference equality comparison on serialization, which is where we use the objects as the dictionary keys. _objectToReferenceIdMap = new Dictionary<object, string>(ReferenceEqualityComparer.Instance); } else { _referenceIdToObjectMap = new Dictionary<string, object>(); } } public override void AddReference(string referenceId, object value) { Debug.Assert(_referenceIdToObjectMap is not null); if (!_referenceIdToObjectMap.TryAdd(referenceId, value)) { ThrowHelper.ThrowJsonException_MetadataDuplicateIdFound(referenceId); } } public override string GetReference(object value, out bool alreadyExists) { Debug.Assert(_objectToReferenceIdMap is not null); if (_objectToReferenceIdMap.TryGetValue(value, out string? referenceId)) { alreadyExists = true; } else { _referenceCount++; referenceId = _referenceCount.ToString(); _objectToReferenceIdMap.Add(value, referenceId); alreadyExists = false; } return referenceId; } public override object ResolveReference(string referenceId) { Debug.Assert(_referenceIdToObjectMap is not null); if (!_referenceIdToObjectMap.TryGetValue(referenceId, out object? value)) { ThrowHelper.ThrowJsonException_MetadataReferenceNotFound(referenceId); } return value; } } }