From: Jeremy Kuhne Date: Mon, 15 Jul 2019 19:42:55 +0000 (-0700) Subject: Make CreateConverter public and add options (dotnet/corefx#39438) X-Git-Tag: submit/tizen/20210909.063632~11031^2~937 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1f8420b4162e55f28ebd6bcf17592fc390def3e5;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Make CreateConverter public and add options (dotnet/corefx#39438) * Make CreateConverter public and add options This is to facilitate composition with factory converters. * Remove unnecessary using Commit migrated from https://github.com/dotnet/corefx/commit/db543576d757f2d448f004f5e9ba2b77c2b497fe --- diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index ee3663c..82bc52d 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -467,7 +467,7 @@ namespace System.Text.Json.Serialization public abstract partial class JsonConverterFactory : System.Text.Json.Serialization.JsonConverter { protected internal JsonConverterFactory() { } - protected abstract System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert); + public abstract System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); } public abstract partial class JsonConverter : System.Text.Json.Serialization.JsonConverter { @@ -497,6 +497,6 @@ namespace System.Text.Json.Serialization public JsonStringEnumConverter() { } public JsonStringEnumConverter(System.Text.Json.JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true) { } public override bool CanConvert(System.Type typeToConvert) { throw null; } - protected override System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert) { throw null; } + public override System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { throw null; } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs index aada8d1..7cdada1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs @@ -17,7 +17,7 @@ namespace System.Text.Json.Serialization.Converters return type.IsEnum; } - protected override JsonConverter CreateConverter(Type type) + public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) { JsonConverter converter = (JsonConverter)Activator.CreateInstance( typeof(JsonConverterEnum<>).MakeGenericType(type), diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs index 833bb0a..90d3128 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs @@ -18,7 +18,7 @@ namespace System.Text.Json.Serialization.Converters return (generic == typeof(KeyValuePair<,>)); } - protected override JsonConverter CreateConverter(Type type) + public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) { Type keyType = type.GetGenericArguments()[0]; Type valueType = type.GetGenericArguments()[1]; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs index a4585fc..5e4d686 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs @@ -19,19 +19,20 @@ namespace System.Text.Json.Serialization /// protected internal JsonConverterFactory() { } - internal JsonConverter GetConverterInternal(Type typeToConvert) + internal JsonConverter GetConverterInternal(Type typeToConvert, JsonSerializerOptions options) { Debug.Assert(CanConvert(typeToConvert)); - return CreateConverter(typeToConvert); + return CreateConverter(typeToConvert, options); } /// /// Create a converter for the provided . /// - /// The type to convert. + /// The being converted. + /// The being used. /// /// An instance of a where T is compatible with . - /// - protected abstract JsonConverter CreateConverter(Type typeToConvert); + /// + public abstract JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index 6152dc8..12980ec 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs @@ -88,7 +88,7 @@ namespace System.Text.Json if (converter is JsonConverterFactory factory) { - converter = factory.GetConverterInternal(runtimePropertyType); + converter = factory.GetConverterInternal(runtimePropertyType, this); } return converter; @@ -154,7 +154,7 @@ namespace System.Text.Json // Allow redirection for generic types or the enum converter. if (converter is JsonConverterFactory factory) { - converter = factory.GetConverterInternal(typeToConvert); + converter = factory.GetConverterInternal(typeToConvert, this); if (converter == null || converter.TypeToConvert == null) { throw new ArgumentNullException("typeToConvert"); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs index aeaa8f6..2cbd3a1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs @@ -53,7 +53,7 @@ namespace System.Text.Json.Serialization } /// - protected override JsonConverter CreateConverter(Type typeToConvert) + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { JsonConverter converter = (JsonConverter)Activator.CreateInstance( typeof(JsonConverterEnum<>).MakeGenericType(typeToConvert), diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs index a6aed82..3740241 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs @@ -87,7 +87,7 @@ namespace System.Text.Json.Serialization.Tests return true; } - protected override JsonConverter CreateConverter(Type typeToConvert) + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { return null; } diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.List.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.List.cs index 35ea08d..4ff3b0d 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.List.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.List.cs @@ -35,7 +35,7 @@ namespace System.Text.Json.Serialization.Tests arg == typeof(long); } - protected override JsonConverter CreateConverter(Type type) + public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) { Type elementType = type.GetGenericArguments()[0]; diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.cs index c277a79..cb0fb03 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.cs @@ -31,5 +31,39 @@ namespace System.Text.Json.Serialization.Tests string jsonElementString = jsonElement.ToString(); Assert.Equal(expectedJson, jsonElementString); } + + [Fact] + public static void OptionsArePassedToCreateConverter() + { + TestFactory factory = new TestFactory(); + JsonSerializerOptions options = new JsonSerializerOptions { Converters = { factory } }; + string json = JsonSerializer.Serialize("Test", options); + Assert.Equal(@"""Test""", json); + Assert.Same(options, factory.Options); + } + + public class TestFactory : JsonConverterFactory + { + public JsonSerializerOptions Options { get; private set; } + + public override bool CanConvert(Type typeToConvert) => true; + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + Options = options; + return new SimpleConverter(); + } + + public class SimpleConverter : JsonConverter + { + public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + => writer.WriteStringValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/EnumConverterTests.cs b/src/libraries/System.Text.Json/tests/Serialization/EnumConverterTests.cs index bd6c6d2..17447fd 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/EnumConverterTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/EnumConverterTests.cs @@ -144,5 +144,26 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal(DayOfWeek.Friday, week.WorkEnd); Assert.Equal(DayOfWeek.Saturday, week.WeekEnd); } + + [Fact] + public void EnumConverterComposition() + { + JsonSerializerOptions options = new JsonSerializerOptions { Converters = { new NoFlagsStringEnumConverter() } }; + string json = JsonSerializer.Serialize(DayOfWeek.Monday, options); + Assert.Equal(@"""Monday""", json); + json = JsonSerializer.Serialize(FileAccess.Read); + Assert.Equal(@"1", json); + } + + public class NoFlagsStringEnumConverter : JsonConverterFactory + { + private static JsonStringEnumConverter s_stringEnumConverter = new JsonStringEnumConverter(); + + public override bool CanConvert(Type typeToConvert) + => typeToConvert.IsEnum && !typeToConvert.IsDefined(typeof(FlagsAttribute), inherit: false); + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + => s_stringEnumConverter.CreateConverter(typeToConvert, options); + } } }