-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDIctionaryToObjectConverter.cs
More file actions
112 lines (96 loc) · 3.71 KB
/
DIctionaryToObjectConverter.cs
File metadata and controls
112 lines (96 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
public class DictionaryToObjectConverter
{
public T Convert<T>(Dictionary<string, object> dictionary) where T : new()
{
T obj = new T();
foreach (var kvp in dictionary)
{
string propertyName = kvp.Key;
object propertyValue = kvp.Value;
PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (propertyInfo != null && propertyInfo.CanWrite)
{
Type propertyType = propertyInfo.PropertyType;
if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>))
{
propertyValue = ConvertList(propertyValue, propertyType);
}
else if (propertyValue is Dictionary<string, object> nestedDictionary)
{
propertyValue = ConvertNestedDictionary(nestedDictionary, propertyType);
}
else
{
propertyValue = ConvertValue(propertyValue, propertyType);
}
propertyInfo.SetValue(obj, propertyValue);
}
}
return obj;
}
private object ConvertValue(object value, Type targetType)
{
if (value == null)
return null;
Type valueType = value.GetType();
if (targetType.IsAssignableFrom(valueType))
return value;
TypeConverter converter = TypeDescriptor.GetConverter(targetType);
if (converter.CanConvertFrom(valueType))
{
return converter.ConvertFrom(value);
}
else if (targetType.IsEnum && value is string stringValue)
{
return Enum.Parse(targetType, stringValue, ignoreCase: true);
}
else if (targetType == typeof(Guid))
{
return new Guid(value.ToString());
}
else
{
try
{
return System.Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture);
}
catch (InvalidCastException)
{
throw new InvalidOperationException($"Cannot convert value '{value}' to type '{targetType}'.");
}
}
}
private object ConvertNestedDictionary(Dictionary<string, object> nestedDictionary, Type targetType)
{
var converterType = typeof(DictionaryToObjectConverter);
var converterMethod = converterType.GetMethod("Convert", BindingFlags.Public | BindingFlags.Instance);
var genericMethod = converterMethod.MakeGenericMethod(targetType);
return genericMethod.Invoke(this, new object[] { nestedDictionary });
}
private object ConvertList(object value, Type targetType)
{
Type elementType = targetType.GetGenericArguments()[0];
Type listType = typeof(List<>).MakeGenericType(elementType);
IList list = (IList)Activator.CreateInstance(listType);
foreach (var item in (IEnumerable)value)
{
object convertedItem;
if (item is Dictionary<string, object> nestedDictionary)
{
convertedItem = ConvertNestedDictionary(nestedDictionary, elementType);
}
else
{
convertedItem = ConvertValue(item, elementType);
}
list.Add(convertedItem);
}
return list;
}
}