-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Provide an API for configuring JsonSerializerOptions
instances for reflection-based serialization.
#89934
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsBackground & MotivationThe System.Text.Json reflection-based serializer makes it possible for users to supply Using publicly available APIs, this semantic can be emulated as follows: void ConfigureForReflection(JsonSerializerOptions options)
{
options.TypeInfoResolver ??= new DefaultJsonTypeInfoResolver();
options.MakeReadOnly();
} The problem with this approach is that it isn't thread safe when applied to the same if (options.TypeInfoResolver is null)
{
// Run a basic serialization operation to force thread-safe initialization of the options instance.
JsonSerializer.Deserialize<int>("0"u8, options);
} While the above works, it is kind of wasteful in that it forces an unnecessary serialization operation. We need access to the API that simply primes the options instance for reflection-based usage. API ProposalAdd a method to namespace System.Text.Json;
public partial class JsonSerializerOptions
{
// Throws IOE if TypeInfoResolver is null
public void MakeReadOnly();
+ // Populates TypeInfoResolver to DefaultJsonTypeInfoResolver if null
+ // (or the empty resolver if the IsReflectionEnabledDefault switch is disabled)
+ public void MakeReadOnlyWithReflectionDefaults();
} cc @eerhardt
|
Rather than a distinct name (largely because we couldn't come up with one), we added a bool parameter, where false matches the existing (AOT-friendly) behavior, and true means "just make it work". If it feels "natural", consider [ConstantExpected(Min=true,Max=true)]. namespace System.Text.Json
{
public partial class JsonSerializerOptions
{
// Existing
// Throws IOE if TypeInfoResolver is null
public void MakeReadOnly();
[RequiresUnreferencedCode, RequiresDynamicCode]
public void MakeReadOnly(bool populateMissingResolver);
}
} |
One hiccup that I found with |
Background & Motivation
The System.Text.Json reflection-based serializer makes it possible for users to supply
JsonSerializerOptions
instances that don't have aTypeInfoResolver
property explicitly configured. It does this by silently populating theTypeInfoResolver
property with a reflection-basedDefaultJsonTypeInfoResolver
value and then locking the instance for further modification.Using publicly available APIs, this semantic can be emulated as follows:
The problem with this approach is that it isn't thread safe when applied to the same
options
instance. I encountered this issue when attempting to implement reflection-based initialization inSystem.Net.Http.Json
(cf. #89830), which can only access public STJ APIs. At the moment, the only viable workaround for libraries likeSystem.Net.Http.Json
is to do the following:While the above works, it is kind of wasteful in that it forces an unnecessary serialization operation. We need access to the API that simply primes the options instance for reflection-based usage.
API Proposal
Add a method to
JsonSerializerOptions
for configuring using reflection-based defaults:cc @eerhardt
The text was updated successfully, but these errors were encountered: