public sealed override object Convert(object?value, ConverterSettings settings) { if (value == null) { throw new ArgumentNullException(nameof(value)); } return(ToDictionary((T)value, settings)); }
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); }
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); }
public abstract object Convert(object?value, ConverterSettings settings);
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); }
public abstract T ToInstance(IDictionary <string, object?> value, ConverterSettings settings);
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); }
public abstract T ConvertBack(object value, ConverterSettings settings);