NServiceBus.XmlDeserialization.GetPropertyValue C# (CSharp) Method

GetPropertyValue() private method

private GetPropertyValue ( Type type, XmlNode n ) : object
type System.Type
n System.Xml.XmlNode
return object
        object GetPropertyValue(Type type, XmlNode n)
        {
            if ((n.ChildNodes.Count == 1) && n.ChildNodes[0] is XmlCharacterData)
            {
                var text = n.ChildNodes[0].InnerText;

                var args = type.GetGenericArguments();
                if (args.Length == 1 && args[0].IsValueType)
                {
                    if (args[0].GetGenericArguments().Any())
                    {
                        return GetPropertyValue(args[0], n);
                    }

                    var nullableType = typeof(Nullable<>).MakeGenericType(args);
                    if (type == nullableType)
                    {
                        if (text.Trim().ToLower() == "null" || string.IsNullOrWhiteSpace(text))
                        {
                            return null;
                        }

                        return GetPropertyValue(args[0], n);
                    }
                }

                if (type == typeof(string))
                {
                    return text;
                }

                if (type == typeof(bool))
                {
                    return XmlConvert.ToBoolean(text);
                }

                if (type == typeof(byte))
                {
                    return XmlConvert.ToByte(text);
                }

                if (type == typeof(char))
                {
                    return XmlConvert.ToChar(text);
                }

                if (type == typeof(DateTime))
                {
                    return XmlConvert.ToDateTime(text, XmlDateTimeSerializationMode.RoundtripKind);
                }

                if (type == typeof(DateTimeOffset))
                {
                    return XmlConvert.ToDateTimeOffset(text);
                }

                if (type == typeof(decimal))
                {
                    return XmlConvert.ToDecimal(text);
                }

                if (type == typeof(double))
                {
                    return XmlConvert.ToDouble(text);
                }

                if (type == typeof(Guid))
                {
                    return XmlConvert.ToGuid(text);
                }

                if (type == typeof(short))
                {
                    return XmlConvert.ToInt16(text);
                }

                if (type == typeof(int))
                {
                    return XmlConvert.ToInt32(text);
                }

                if (type == typeof(long))
                {
                    return XmlConvert.ToInt64(text);
                }

                if (type == typeof(sbyte))
                {
                    return XmlConvert.ToSByte(text);
                }

                if (type == typeof(float))
                {
                    return XmlConvert.ToSingle(text);
                }

                if (type == typeof(TimeSpan))
                {
                    return XmlConvert.ToTimeSpan(text);
                }

                if (type == typeof(ushort))
                {
                    return XmlConvert.ToUInt16(text);
                }

                if (type == typeof(uint))
                {
                    return XmlConvert.ToUInt32(text);
                }

                if (type == typeof(ulong))
                {
                    return XmlConvert.ToUInt64(text);
                }

                if (type.IsEnum)
                {
                    return Enum.Parse(type, text);
                }

                if (type == typeof(byte[]))
                {
                    return Convert.FromBase64String(text);
                }

                if (type == typeof(Uri))
                {
                    return new Uri(text);
                }

                if (!typeof(IEnumerable).IsAssignableFrom(type))
                {
                    if (n.ChildNodes[0] is XmlWhitespace)
                    {
                        return Activator.CreateInstance(type);
                    }

                    throw new Exception($"Type not supported by the serializer: {type.AssemblyQualifiedName}");
                }
            }

            if (typeof(XContainer).IsAssignableFrom(type))
            {
                var reader = new StringReader(skipWrappingRawXml ? n.OuterXml : n.InnerXml);

                if (type == typeof(XDocument))
                {
                    return XDocument.Load(reader);
                }

                return XElement.Load(reader);
            }

            //Handle dictionaries
            if (typeof(IDictionary).IsAssignableFrom(type))
            {
                var result = Activator.CreateInstance(type) as IDictionary;

                var keyType = typeof(object);
                var valueType = typeof(object);

                foreach (var interfaceType in type.GetInterfaces())
                {
                    var args = interfaceType.GetGenericArguments();
                    if (args.Length != 2)
                    {
                        continue;
                    }

                    if (typeof(IDictionary<,>).MakeGenericType(args[0], args[1]).IsAssignableFrom(type))
                    {
                        keyType = args[0];
                        valueType = args[1];
                        break;
                    }
                }

                foreach (XmlNode xn in n.ChildNodes) // go over KeyValuePairs
                {
                    object key = null;
                    object value = null;

                    foreach (XmlNode node in xn.ChildNodes)
                    {
                        if (node.Name == "Key")
                        {
                            key = GetObjectOfTypeFromNode(keyType, node);
                        }
                        if (node.Name == "Value")
                        {
                            value = GetObjectOfTypeFromNode(valueType, node);
                        }
                    }

                    if (result != null && key != null)
                    {
                        result[key] = value;
                    }
                }

                return result;
            }

            if (typeof(IEnumerable).IsAssignableFrom(type) && type != typeof(string))
            {
                var isArray = type.IsArray;

                var isISet = false;
                if (type.IsGenericType && type.GetGenericArguments().Length == 1)
                {
                    var setType = typeof(ISet<>).MakeGenericType(type.GetGenericArguments());
                    isISet = setType.IsAssignableFrom(type);
                }

                var typeToCreate = type;
                if (isArray)
                {
                    typeToCreate = cache.typesToCreateForArrays[type];
                }

                Type typeToCreateForEnumerables;
                if (cache.typesToCreateForEnumerables.TryGetValue(type, out typeToCreateForEnumerables)) //handle IEnumerable<Something>
                {
                    typeToCreate = typeToCreateForEnumerables;
                }

                if (typeof(IList).IsAssignableFrom(typeToCreate))
                {
                    var list = Activator.CreateInstance(typeToCreate) as IList;
                    if (list != null)
                    {
                        foreach (XmlNode xn in n.ChildNodes)
                        {
                            if (xn.NodeType == XmlNodeType.Whitespace)
                            {
                                continue;
                            }

                            var m = Process(xn, list);
                            list.Add(m);
                        }

                        if (isArray)
                        {
                            return typeToCreate.GetMethod("ToArray").Invoke(list, null);
                        }

                        if (isISet)
                        {
                            return Activator.CreateInstance(type, typeToCreate.GetMethod("ToArray").Invoke(list, null));
                        }
                    }

                    return list;
                }
            }

            if (n.ChildNodes.Count == 0)
            {
                if (type == typeof(string))
                {
                    return string.Empty;
                }
                return null;
            }

            return GetObjectOfTypeFromNode(type, n);
        }