From 903d61a95220833430bec2108a9d3a7ccf7dc2b2 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Tue, 17 Nov 2020 00:02:38 +0100 Subject: [PATCH] Refined converter API (#2593) --- ...Setup.cs => DefaultTypeConverter.Setup.cs} | 0 .../Types/Utilities/DefaultTypeConverter.cs | 31 +++++++++--------- .../src/Types/Utilities/EnumTypeConverter.cs | 8 ++--- .../Types/Utilities/IChangeTypeProvider.cs | 32 +++++++++++++++++-- ...tensions.cs => TypeConverterExtensions.cs} | 0 5 files changed, 49 insertions(+), 22 deletions(-) rename src/HotChocolate/Core/src/Types/Utilities/{TypeConversion.Setup.cs => DefaultTypeConverter.Setup.cs} (100%) rename src/HotChocolate/Core/src/Types/Utilities/{TypeConversionExtensions.cs => TypeConverterExtensions.cs} (100%) diff --git a/src/HotChocolate/Core/src/Types/Utilities/TypeConversion.Setup.cs b/src/HotChocolate/Core/src/Types/Utilities/DefaultTypeConverter.Setup.cs similarity index 100% rename from src/HotChocolate/Core/src/Types/Utilities/TypeConversion.Setup.cs rename to src/HotChocolate/Core/src/Types/Utilities/DefaultTypeConverter.Setup.cs diff --git a/src/HotChocolate/Core/src/Types/Utilities/DefaultTypeConverter.cs b/src/HotChocolate/Core/src/Types/Utilities/DefaultTypeConverter.cs index dccb6e51a30..95a814f48bd 100644 --- a/src/HotChocolate/Core/src/Types/Utilities/DefaultTypeConverter.cs +++ b/src/HotChocolate/Core/src/Types/Utilities/DefaultTypeConverter.cs @@ -8,13 +8,10 @@ namespace HotChocolate.Utilities { - public partial class DefaultTypeConverter - : ITypeConverter + public partial class DefaultTypeConverter : ITypeConverter { - private readonly ConcurrentDictionary> _converters = - new ConcurrentDictionary>(); - private readonly List _changeTypeProvider = - new List(); + private readonly ConcurrentDictionary<(Type, Type), ChangeType> _converters = new(); + private readonly List _changeTypeProvider = new(); public DefaultTypeConverter(IEnumerable? providers = null) { @@ -107,11 +104,16 @@ private bool TryConvertInternal(Type from, Type to, object source, out object? c Type to, [NotNullWhen(true)] out ChangeType? converter) { - if (TryGetConverter(from, to, out converter) - || TryCreateConverterFromFactory(from, to, out converter)) + if (TryGetConverter(from, to, out converter)) { return true; } + + if (TryCreateConverterFromFactory(from, to, out converter)) + { + return true; + } + return false; } @@ -127,6 +129,7 @@ private bool TryConvertInternal(Type from, Type to, object source, out object? c if (provider.TryCreateConverter( source, target, TryGetOrCreateConverter, out converter)) { + _converters.TryAdd((source, target), converter); return true; } } @@ -143,16 +146,12 @@ private bool TryConvertInternal(Type from, Type to, object source, out object? c { if (source == target || target == typeof(object)) { - converter = source => source; + converter = s => s; return true; } - if (_converters.TryGetValue(source, - out ConcurrentDictionary? toLookUp) - && toLookUp.TryGetValue(target, - out ChangeType? changeType)) + if (_converters.TryGetValue((source, target), out converter)) { - converter = changeType; return true; } @@ -173,7 +172,7 @@ private bool TryConvertInternal(Type from, Type to, object source, out object? c return converter((TSource)input); })); - public static DefaultTypeConverter Default { get; } = new DefaultTypeConverter(); + public static DefaultTypeConverter Default { get; } = new(); private sealed class DelegateTypeConverter : IChangeTypeProvider { @@ -205,4 +204,4 @@ public DelegateTypeConverter(Type source, Type target, ChangeType converter) } } } -} \ No newline at end of file +} diff --git a/src/HotChocolate/Core/src/Types/Utilities/EnumTypeConverter.cs b/src/HotChocolate/Core/src/Types/Utilities/EnumTypeConverter.cs index 9fe7a78a424..e5404d2467d 100644 --- a/src/HotChocolate/Core/src/Types/Utilities/EnumTypeConverter.cs +++ b/src/HotChocolate/Core/src/Types/Utilities/EnumTypeConverter.cs @@ -6,9 +6,9 @@ namespace HotChocolate.Utilities internal sealed class EnumTypeConverter : IChangeTypeProvider { public bool TryCreateConverter( - Type source, - Type target, - ChangeTypeProvider root, + Type source, + Type target, + ChangeTypeProvider root, [NotNullWhen(true)] out ChangeType converter) { if (source == typeof(string) && target.IsEnum) @@ -19,7 +19,7 @@ internal sealed class EnumTypeConverter : IChangeTypeProvider if (source.IsEnum && target == typeof(string)) { - converter = input => input.ToString(); + converter = input => input?.ToString(); return true; } diff --git a/src/HotChocolate/Core/src/Types/Utilities/IChangeTypeProvider.cs b/src/HotChocolate/Core/src/Types/Utilities/IChangeTypeProvider.cs index 56fb3a84ac0..c1c22901371 100644 --- a/src/HotChocolate/Core/src/Types/Utilities/IChangeTypeProvider.cs +++ b/src/HotChocolate/Core/src/Types/Utilities/IChangeTypeProvider.cs @@ -5,11 +5,39 @@ namespace HotChocolate.Utilities { + /// + /// A is used by the type converter to create new converter. + /// Each can provide one ore multiple value converters. + /// public interface IChangeTypeProvider { + /// + /// Tries to create a converter that can convert a value that is of the + /// type to a value of the type . + /// If this type provider can only handle parts of the conversion it can refer back to the + /// root converter to ask other to provide the rest of + /// the type conversion. + /// + /// + /// The source type. + /// + /// + /// The traget type. + /// + /// + /// The root change type provider that has access to + /// all registered . + /// + /// + /// The converter that was produced by this instance. + /// + /// + /// Returns a boolean indicating if this was able to + /// create a type converter. + /// bool TryCreateConverter( - Type source, - Type target, + Type source, + Type target, ChangeTypeProvider root, [NotNullWhen(true)]out ChangeType? converter); } diff --git a/src/HotChocolate/Core/src/Types/Utilities/TypeConversionExtensions.cs b/src/HotChocolate/Core/src/Types/Utilities/TypeConverterExtensions.cs similarity index 100% rename from src/HotChocolate/Core/src/Types/Utilities/TypeConversionExtensions.cs rename to src/HotChocolate/Core/src/Types/Utilities/TypeConverterExtensions.cs