Skip to content

Commit

Permalink
Add JsonSerializerOptions.Default (#61434)
Browse files Browse the repository at this point in the history
* Add JsonSerializerOptions.Default

* address feedback

* address feedback
  • Loading branch information
eiriktsarpalis authored Nov 15, 2021
1 parent 0681dd6 commit 89d967b
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/libraries/System.Text.Json/System.Text.Json.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Encodings.Web",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Encodings.Web", "..\System.Text.Encodings.Web\src\System.Text.Encodings.Web.csproj", "{9BCCDA15-8907-4AE3-8871-2F17775DDE4C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration", "gen\System.Text.Json.SourceGeneration.Roslyn3.11.csproj", "{04AEB008-EE4F-44DE-A361-2DBD2D0FD6A4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn3.11", "gen\System.Text.Json.SourceGeneration.Roslyn3.11.csproj", "{04AEB008-EE4F-44DE-A361-2DBD2D0FD6A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration", "gen\System.Text.Json.SourceGeneration.Roslyn4.0.csproj", "{6485EED4-C313-4551-9865-8ADCED603629}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json.SourceGeneration.Roslyn4.0", "gen\System.Text.Json.SourceGeneration.Roslyn4.0.csproj", "{6485EED4-C313-4551-9865-8ADCED603629}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Text.Json", "ref\System.Text.Json.csproj", "{7015E94D-D20D-48C8-86D7-6A996BE99E0E}"
EndProject
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ public JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults defaults) {
public JsonSerializerOptions(System.Text.Json.JsonSerializerOptions options) { }
public bool AllowTrailingCommas { get { throw null; } set { } }
public System.Collections.Generic.IList<System.Text.Json.Serialization.JsonConverter> Converters { get { throw null; } }
public static System.Text.Json.JsonSerializerOptions Default { get { throw null; } }
public int DefaultBufferSize { get { throw null; } set { } }
public System.Text.Json.Serialization.JsonIgnoreCondition DefaultIgnoreCondition { get { throw null; } set { } }
public System.Text.Json.JsonNamingPolicy? DictionaryKeyPolicy { get { throw null; } set { } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? optio
CreateNodes();
Debug.Assert(_list != null);

options ??= JsonSerializerOptions.s_defaultOptions;
options ??= JsonSerializerOptions.Default;

writer.WriteStartArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? optio
}
else
{
options ??= JsonSerializerOptions.s_defaultOptions;
options ??= JsonSerializerOptions.Default;

writer.WriteStartObject();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? optio

if (_converter != null)
{
options ??= JsonSerializerOptions.s_defaultOptions;
options ??= JsonSerializerOptions.Default;

if (_converter.IsInternalConverterForNumberType)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ private static JsonTypeInfo GetTypeInfo(JsonSerializerOptions? options, Type run
{
Debug.Assert(runtimeType != null);

options ??= JsonSerializerOptions.s_defaultOptions;
options ??= JsonSerializerOptions.Default;
if (!options.IsInitializedForReflectionSerializer)
{
options.InitializeForReflectionSerializer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ public static partial class JsonSerializer
throw new ArgumentNullException(nameof(utf8Json));
}

options ??= JsonSerializerOptions.s_defaultOptions;
options ??= JsonSerializerOptions.Default;
if (!options.IsInitializedForReflectionSerializer)
{
options.InitializeForReflectionSerializer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ public sealed partial class JsonSerializerOptions
{
internal const int BufferSizeDefault = 16 * 1024;

internal static readonly JsonSerializerOptions s_defaultOptions = new JsonSerializerOptions();
/// <summary>
/// Gets a read-only, singleton instance of <see cref="JsonSerializerOptions" /> that uses the default configuration.
/// </summary>
/// <remarks>
/// Each <see cref="JsonSerializerOptions" /> instance encapsulates its own serialization metadata caches,
/// so using fresh default instances every time one is needed can result in redundant recomputation of converters.
/// This property provides a shared instance that can be consumed by any number of components without necessitating any converter recomputation.
/// </remarks>
public static JsonSerializerOptions Default { get; } = new JsonSerializerOptions { _haveTypesBeenCreated = true };

private readonly ConcurrentDictionary<Type, JsonTypeInfo> _classes = new ConcurrentDictionary<Type, JsonTypeInfo>();

Expand Down Expand Up @@ -709,9 +717,6 @@ internal JsonWriterOptions GetWriterOptions()

internal void VerifyMutable()
{
// The default options are hidden and thus should be immutable.
Debug.Assert(this != s_defaultOptions);

if (_haveTypesBeenCreated || _context != null)
{
ThrowHelper.ThrowInvalidOperationException_SerializerOptionsImmutable(_context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,28 @@ public static void CopyConstructor_NullInput()
Assert.Contains("options", ex.ToString());
}

[Fact]
public static void JsonSerializerOptions_Default_MatchesDefaultConstructor()
{
var options = new JsonSerializerOptions();
JsonSerializerOptions optionsSingleton = JsonSerializerOptions.Default;
VerifyOptionsEqual(options, optionsSingleton);
}

[Fact]
public static void JsonSerializerOptions_Default_ReturnsSameInstance()
{
Assert.Same(JsonSerializerOptions.Default, JsonSerializerOptions.Default);
}

[Fact]
public static void JsonSerializerOptions_Default_IsReadOnly()
{
var optionsSingleton = JsonSerializerOptions.Default;
Assert.Throws<InvalidOperationException>(() => optionsSingleton.IncludeFields = true);
Assert.Throws<InvalidOperationException>(() => optionsSingleton.Converters.Add(new JsonStringEnumConverter()));
}

[Fact]
public static void DefaultSerializerOptions_General()
{
Expand Down Expand Up @@ -542,7 +564,7 @@ private static JsonSerializerOptions GetFullyPopulatedOptionsInstance()
{
var options = new JsonSerializerOptions();

foreach (PropertyInfo property in typeof(JsonSerializerOptions).GetProperties())
foreach (PropertyInfo property in typeof(JsonSerializerOptions).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
Type propertyType = property.PropertyType;

Expand Down Expand Up @@ -596,7 +618,7 @@ private static JsonSerializerOptions GetFullyPopulatedOptionsInstance()

private static void VerifyOptionsEqual(JsonSerializerOptions options, JsonSerializerOptions newOptions)
{
foreach (PropertyInfo property in typeof(JsonSerializerOptions).GetProperties())
foreach (PropertyInfo property in typeof(JsonSerializerOptions).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
Type propertyType = property.PropertyType;

Expand Down

0 comments on commit 89d967b

Please sign in to comment.