Closed
Description
The current iteration of JsonSerializerOptions.TypeInfoResolver
is implemented as non-nullable and marked as
RequiredUnreferencedCode
since by default it will return the reflection-based contract resolver. This has been informed by the existing semantics of the JsonSerializer
methods accepting JsonSerializerOptions
as an argument: unless a contract resolver is explicitly set the method will revert to using reflection-based serialization.
I believe however that this approach is problematic, for a number of reasons:
- Because the property is marked RUC, it can trigger linker warnings in otherwise innocuous operations, such as copying resolver configuration to a new options instance.
- The introduction of contract customization has effectively decoupled reflection-based serialization from
JsonSerializerOptions
. While we cannot change the semantics of existingJsonSerializer
methods it is conceivable that future serialization APIs can make use of it in a linker-safe manner. Assuming we ship theTypeInfoResolver
property in the current manifestation, we forever coupleJsonSerializerOptions
to the reflection-based serialization and trimmability concerns.
I propose we make the following changes to the API:
public partial class JsonSerializerOptions
{
- [RequiresUnreferenceCode]
- [RequiresDynamicCode]
- public IJsonTypeInfoResolver TypeInfoResolver { get; set; }
+ public IJsonTypeInfoResolver? TypeInfoResolver { get; set; }
+ [RequiresUnreferenceCode]
+ [RequiresDynamicCode]
public static JsonSerializerOptions Default { get; } // default instance comes populated with reflection resolver
}