示例#1
0
        private object HandleListDerivative(XElement root, string propName, Type type)
        {
            Type realType = type.IsGenericType
                ? type.GetGenericArguments()[0]
                : type.BaseType.GetGenericArguments()[0];

            IList list = (IList)Activator.CreateInstance(type);

            string name = realType.Name;

            SerializeInfoAttribute attribute = realType.GetCustomAttribute <SerializeInfoAttribute>();

            if (attribute != null)
            {
                name = attribute.Name;
            }

            IEnumerable <XElement> elements = FindDescendants(root, name);

            PopulateListFromElements(realType, elements, list);

            if (!type.IsGenericType)
            {
                Map(list, root.Element(propName) ?? root);
            }

            return(list);
        }
示例#2
0
        private object Map(object x, XElement root)
        {
            Type objType = x.GetType();

            PropertyInfo[] props = objType.GetProperties();

            foreach (PropertyInfo prop in props)
            {
                Type type         = prop.PropertyType;
                bool typeIsPublic = type.IsPublic || type.IsNestedPublic;

                if (!typeIsPublic || !prop.CanWrite)
                {
                    continue;
                }

                XName name   = prop.Name;
                bool  isAttr = false;

                SerializeInfoAttribute attribute = prop.GetCustomAttribute <SerializeInfoAttribute>(false);

                if (attribute != null)
                {
                    name   = attribute.Name;
                    isAttr = attribute.IsAttribute;
                }

                string value = GetValueFromXml(root, name, isAttr);

                //We have 2 case for lists. The first one:
                //
                //<list>
                //  <item></item>
                //  <item></item>
                //</list>
                //
                //In this case we use the property's real name to find the container and map the items from children

                //Second one:
                //
                //<item></item>
                //<item></item>
                //
                //In this case we use the generic type's real name and use the root to find the children

                if (value == null)
                {
                    if (type.IsGenericType)
                    {
                        Type genericType = type.GetGenericArguments()[0];

                        string realName = genericType.Name;

                        SerializeInfoAttribute attr = genericType.GetCustomAttribute <SerializeInfoAttribute>();

                        if (attr != null)
                        {
                            realName = attr.Name;
                        }

                        XElement first = GetElementByName(root, realName);
                        IList    list  = (IList)Activator.CreateInstance(type);

                        if (first != null && root != null)
                        {
                            IEnumerable <XElement> elements = root.Elements(first.Name);

                            PopulateListFromElements(genericType, elements, list);
                        }

                        prop.SetValue(x, list, null);
                    }

                    continue;
                }

                if (TryParseSimpleValue(value, type, out object parsedValue))
                {
                    prop.SetValue(x, parsedValue, null);
                    continue;
                }

                //If it wasn't a supported primitive type, objVal is null here

                if (type.IsGenericType)
                {
                    if (type.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        prop.SetValue(x, null, null);
                        continue;
                    }

                    IList    list      = (IList)Activator.CreateInstance(type);
                    XElement container = GetElementByName(root, name);

                    if (container.HasElements)
                    {
                        XElement first = container.Elements().FirstOrDefault();

                        if (first != null)
                        {
                            Type t = type.GetGenericArguments()[0];
                            IEnumerable <XElement> elements = container.Elements(first.Name);

                            PopulateListFromElements(t, elements, list);
                        }
                    }

                    prop.SetValue(x, list, null);
                }
                else if (typeof(List <>).IsAssignableFrom(type))
                {
                    object objVal = HandleListDerivative(root, prop.Name, type);

                    if (objVal != null)
                    {
                        prop.SetValue(x, objVal, null);
                    }
                }
                else
                {
                    // nested property classes
                    if (root == null)
                    {
                        continue;
                    }

                    XElement element = GetElementByName(root, name);

                    if (element == null)
                    {
                        continue;
                    }

                    object objVal = CreateAndMap(type, element);

                    if (objVal != null)
                    {
                        prop.SetValue(x, objVal, null);
                    }
                }
            }

            return(x);
        }