示例#1
0
        public sealed override object Convert(object?value, ConverterSettings settings)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            return(ToDictionary((T)value, settings));
        }
示例#2
0
        public sealed override object?ConvertBack(object value, Type type, ConverterSettings settings)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            return(ToInstance((IDictionary <string, object?>)value, settings) as object);
        }
示例#3
0
        public sealed override object?ConvertBack(object value, Type type, ConverterSettings settings)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            return(ConvertBack(value, settings) as object);
        }
示例#4
0
 public abstract object Convert(object?value, ConverterSettings settings);
示例#5
0
 public abstract object?ConvertBack(object value, Type type, ConverterSettings settings);
        internal static IDictionary <string, object?> ToDictionaryInternal(this object instance, ConverterSettings settings)
        {
            var instanceType = instance.GetType();

            if (settings.TryGetMatchingConverter(instanceType, out MemberConverter? converter))
            {
                return((IDictionary <string, object?>)converter.Convert(instance, settings));
            }

            var resolver         = settings.ResolverInternal;
            var members          = resolver.GetMemberInfos(instanceType);
            var resultDictionary = new Dictionary <string, object?>(members.Length);

            foreach (var member in members)
            {
                var key   = member.GetName(resolver);
                var value = member.GetValue(instance, resolver);
                if (value == null || value.GetType().IsSimpleType())
                {
                    resultDictionary[key] = value;
                    continue;
                }

                if (settings.TryGetMatchingConverter(value.GetType(), out converter))
                {
                    resultDictionary[key] = converter.Convert(value, settings);
                    continue;
                }

                resultDictionary[key] = value.ToDictionaryInternal(settings);
            }

            return(resultDictionary);
        }
示例#7
0
 public abstract T ToInstance(IDictionary <string, object?> value, ConverterSettings settings);
示例#8
0
 public abstract IDictionary <string, object> ToDictionary(T value, ConverterSettings settings);
        internal static bool TryConvertGenericValue(object?initialValue, Type memberType, ConverterSettings settings, out object?value)
        {
            value = null;
            if (!memberType.IsGenericType)
            {
                return(false);
            }

            var genTypeDef = memberType.GetGenericTypeDefinition();
            var dict       = initialValue as IDictionary <string, object?> ?? new Dictionary <string, object?>(0);

            // Dictionary
            if (typeof(IDictionary <,>).IsAssignableFrom(genTypeDef) || typeof(Dictionary <,>).IsAssignableFrom(genTypeDef))
            {
                value = DefaultDictionaryConverter.Default.ConvertBack(dict, memberType.GetGenericArguments()[1], settings);
                return(true);
            }

            // Array
            if (typeof(IEnumerable).IsAssignableFrom(genTypeDef))
            {
                value = DefaultEnumerableConverter.Default.ConvertBack(dict, memberType.GetGenericArguments()[0], settings);
                return(true);
            }

            return(false);
        }
        internal static object ToInstanceInternal(this Dictionary <string, object?> dictionary, Type type, ConverterSettings settings)
        {
            if (settings.TryGetMatchingConverter(type, out MemberConverter? converter))
            {
                return(converter.ConvertBack(dictionary, type, settings) ?? throw new InvalidOperationException($"Cannot convert {dictionary.GetType().Name} to {type.Name}"));
            }

            var instance = Activator.CreateInstance(type);
            var resolver = settings.ResolverInternal;
            var members  = resolver.GetMemberInfos(type);

            foreach (var element in dictionary)
            {
                var member = members.FindMatch(element.Key, resolver);
                if (member == null)
                {
                    // Think about a 'AllKeysMustMatch' solution
                    continue;
                }

                var value      = element.Value;
                var memberType = member.GetMemberType();

                if (value != null)
                {
                    // Try to convert non nullable values
                    if (value.TryConvertValue(memberType, settings, out object?conValue))
                    {
                        member.SetValue(instance, conValue);
                        continue;
                    }

                    // Try to use matching converter
                    if (settings.TryGetMatchingConverter(memberType, out converter))
                    {
                        member.SetValue(instance, converter.ConvertBack(value, memberType, settings));
                        continue;
                    }
                }   // Assign null if member type allows null assignment
                else if (!memberType.IsValueType || memberType.TryGetNonNullableType(out Type _))
                {
                    member.SetValue(instance, null);
                    continue;
                }

                // Try to convert generic member
                if (TryConvertGenericValue(value, memberType, settings, out object?genValue))
                {
                    member.SetValue(instance, genValue);
                    continue;
                }

                // Recursive call if value is a dictionary
                if (value is IDictionary dict2)
                {
                    member.SetValue(instance, ((Dictionary <string, object?>)dict2).ToInstanceInternal(memberType, settings));
                    continue;
                }

                throw new NotSupportedException($"'{value?.ToString()}' cannot be assigned to '{member.Name}' or cannot converted to '{memberType.Name}'");
            }

            return(instance);
        }
示例#11
0
 public abstract T ConvertBack(object value, ConverterSettings settings);