Skip to content

Commit

Permalink
Implied resolver implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
krwq committed Jun 7, 2022
1 parent fe6264d commit 89dea87
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ protected JsonSerializerContext(JsonSerializerOptions? options, bool bindOptions
else
{
_options = options;
options.SetImpliedResolver(this);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public bool Equals(JsonSerializerOptions? left, JsonSerializerOptions? right)
left._includeFields == right._includeFields &&
left._propertyNameCaseInsensitive == right._propertyNameCaseInsensitive &&
left._writeIndented == right._writeIndented &&
NormalizeResolver(left._typeInfoResolver) == NormalizeResolver(right._typeInfoResolver) &&
left.NormalizedResolver == right.NormalizedResolver &&
CompareLists(left._converters, right._converters) &&
CompareLists(left._polymorphicTypeConfigurations, right._polymorphicTypeConfigurations);

Expand Down Expand Up @@ -331,7 +331,7 @@ public int GetHashCode(JsonSerializerOptions options)
hc.Add(options._includeFields);
hc.Add(options._propertyNameCaseInsensitive);
hc.Add(options._writeIndented);
hc.Add(NormalizeResolver(options._typeInfoResolver));
hc.Add(options.NormalizedResolver);
GetHashCode(ref hc, options._converters);
GetHashCode(ref hc, options._polymorphicTypeConfigurations);

Expand All @@ -346,10 +346,6 @@ static void GetHashCode<TValue>(ref HashCode hc, ConfigurationList<TValue> list)
return hc.ToHashCode();
}

// An options instance might be locked but not initialized for reflection serialization yet.
private static IJsonTypeInfoResolver? NormalizeResolver(IJsonTypeInfoResolver? resolver)
=> resolver ?? DefaultJsonTypeInfoResolver.DefaultInstance;

#if !NETCOREAPP
/// <summary>
/// Polyfill for System.HashCode.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public sealed partial class JsonSerializerOptions

// For any new option added, adding it to the options copied in the copy constructor below must be considered.
private IJsonTypeInfoResolver? _typeInfoResolver;
// If _typeInfoResolver is not set, we try to use _impliedTypeInfoResolver, if that is not set we use DefaultJsonTypeInfoResolver
private IJsonTypeInfoResolver? _impliedTypeInfoResolver;

// Effective resolver which doesn't root and can be used for GetHashCode or Equals
internal IJsonTypeInfoResolver? NormalizedResolver => _typeInfoResolver ?? _impliedTypeInfoResolver ?? DefaultJsonTypeInfoResolver.DefaultInstance;

private MemberAccessor? _memberAccessorStrategy;
private JsonNamingPolicy? _dictionaryKeyPolicy;
private JsonNamingPolicy? _jsonPropertyNamingPolicy;
Expand Down Expand Up @@ -173,7 +179,7 @@ public IJsonTypeInfoResolver TypeInfoResolver
[RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)]
get
{
return _typeInfoResolver ?? DefaultJsonTypeInfoResolver.RootDefaultInstance();
return NormalizedResolver ?? DefaultJsonTypeInfoResolver.RootDefaultInstance();
}
set
{
Expand Down Expand Up @@ -619,6 +625,18 @@ internal MemberAccessor MemberAccessorStrategy
}
}

private bool _moreThanOneImpliedResolverSet;

// This is used only by JsonSerializerContext ctor which takes options.
// For backward compatibility we need to use context as our resolver
internal void SetImpliedResolver(IJsonTypeInfoResolver resolver)
{
VerifyMutable();

_moreThanOneImpliedResolverSet = _impliedTypeInfoResolver != null;
_impliedTypeInfoResolver = resolver;
}

internal bool IsInitializedForReflectionSerializer { get; private set; }
// Effective resolver, populated when enacting reflection-based fallback
// Should not be taken into account when calculating options equality.
Expand All @@ -631,6 +649,13 @@ internal MemberAccessor MemberAccessorStrategy
[RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)]
internal void InitializeForReflectionSerializer()
{
if (_typeInfoResolver == null && _moreThanOneImpliedResolverSet)
{
ThrowHelper.ThrowInvalidOperationException_SerializerContextOptionsImmutable();
}

_typeInfoResolver ??= _impliedTypeInfoResolver;

if (_typeInfoResolver is JsonSerializerContext ctx)
{
// .NET 6 backward compatibility; use fallback to reflection serialization
Expand Down

0 comments on commit 89dea87

Please sign in to comment.