/// <summary>
        /// Convert xml node into the collection.
        /// </summary>
        /// <param name="node">The node</param>
        /// <param name="collectionType">collection's type.</param>
        /// <param name="configurationReader">The IConfigurationReader instance.</param>
        /// <returns>The collection.</returns>
        public object Map(XmlNode node, Type collectionType, IConfigurationReader configurationReader)
        {
            Type itemType = collectionType.GetElementType();
            var  d1       = typeof(List <>);

            Type[]     typeArgs  = { itemType };
            var        makeme    = d1.MakeGenericType(typeArgs);
            var        list      = Activator.CreateInstance(makeme);
            MethodInfo addMethod = makeme.GetMethod("Add");

            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                XmlNode childNode = node.ChildNodes[i];

                if (itemType.IsPrimitive || itemType == typeof(string) || itemType.IsEnum)
                {
                    IPrimitiveMappingStrategy mappingStrategy = mappingStrategyFactory.CreatePrimitiveStrategy(itemType);
                    var item = mappingStrategy.Map(childNode.InnerText, itemType);
                    addMethod.Invoke(list, new[] { item });
                }
                else
                {
                    IMappingStrategy mappingStrategy = mappingStrategyFactory.CreateComplexStrategy(itemType);
                    var item = mappingStrategy.Map(childNode, itemType, configurationReader);
                    addMethod.Invoke(list, new[] { item });
                }
            }

            MethodInfo toArrayMethod = makeme.GetMethod("ToArray");

            return(toArrayMethod.Invoke(list, null));
        }
Beispiel #2
0
        /// <summary>
        /// Convert xml node into the IDictionary<K, itemType>.
        /// </summary>
        /// <param name="node">The node</param>
        /// <param name="collectionType">Collection's type.</param>
        /// <param name="configurationReader">The IConfigurationReader instance.</param>
        /// <returns>The IDictionary<K, itemType>.</returns>
        /// <exception cref="KeyNotFoundException">There is no key in the collection..</exception>
        /// <exception cref="NotSupportedException">Only primitive keys are supported.</exception>
        /// <exception cref="IndexOutOfRangeException">The value section should contain only one inner element.</exception>
        /// <exception cref="TargetInvocationException">The constructor being called throws an exception. </exception>
        /// <exception cref="AmbiguousMatchException">More than one method is found with the specified name. </exception>
        /// <exception cref="TargetException">In the .NET for Windows Store apps or the Portable Class Library, catch <see cref="T:System.Exception" /> instead.The <paramref name="obj" /> parameter is null and the method is not static.-or- The method is not declared or inherited by the class of <paramref name="obj" />. -or-A static constructor is invoked, and <paramref name="obj" /> is neither null nor an instance of the class that declared the constructor.</exception>
        public object Map(XmlNode node, Type collectionType, IConfigurationReader configurationReader)
        {
            object     dictionary;
            Type       keyType  = collectionType.GetGenericArguments()[0];
            Type       itemType = collectionType.GetGenericArguments()[1];
            MethodInfo addMethod;

            if (collectionType.IsInterface)
            {
                var    d1       = typeof(Dictionary <,>);
                Type[] typeArgs = { keyType, itemType };
                var    makeme   = d1.MakeGenericType(typeArgs);
                dictionary = Activator.CreateInstance(makeme);
                addMethod  = makeme.GetMethod("Add");
            }
            else
            {
                dictionary = Activator.CreateInstance(collectionType);
                addMethod  = collectionType.GetMethod("Add");
            }

            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                XmlNode childNode = node.ChildNodes[i];
                string  keyValue  = childNode.GetNodeValue("key");
                if (string.IsNullOrEmpty(keyValue))
                {
                    string msg = string.Format("There is no 'key' in the {0}.{1}", node.Name, childNode.Name);
                    throw new KeyNotFoundException(msg);
                }

                object key;
                object item;

                if (keyType.IsPrimitive || keyType == typeof(string) || keyType.IsEnum)
                {
                    IPrimitiveMappingStrategy mappingStrategy = mappingStrategyFactory.CreatePrimitiveStrategy(itemType);
                    key = mappingStrategy.Map(keyValue, keyType);
                }
                else
                {
                    string msg = string.Format("{0} as a key not supported.", keyType);
                    throw new NotSupportedException(msg);
                }

                if (itemType.IsPrimitive || itemType == typeof(string) || itemType.IsEnum)
                {
                    IPrimitiveMappingStrategy mappingStrategy = mappingStrategyFactory.CreatePrimitiveStrategy(itemType);
                    string itemValue = childNode.GetNodeValue("value");
                    item = mappingStrategy.Map(itemValue, itemType);
                }
                else
                {
                    XmlNode innerXml = childNode.GetXmlNode("value");

                    if (innerXml.ChildNodes.Count != 1)
                    {
                        string msg = string.Format("The value section should contain only one inner element in the {0}.{1}", childNode.Name, innerXml.Name);
                        throw new IndexOutOfRangeException(msg);
                    }

                    innerXml = innerXml.ChildNodes[0];
                    IMappingStrategy mappingStrategy = mappingStrategyFactory.CreateComplexStrategy(itemType);
                    item = mappingStrategy.Map(innerXml, itemType, configurationReader);
                }

                addMethod.Invoke(dictionary, new[] { key, item });
            }

            return(dictionary);
        }
Beispiel #3
0
        /// <summary>
        /// Read object from the node.
        /// </summary>
        /// <param name="type">The object's type.</param>
        /// <param name="xmlNode">The node.</param>
        /// <returns>The object.</returns>
        public object ReadObject(Type type, XmlNode xmlNode)
        {
            //if (type.Name.ToLower() != xmlNode.Name.ToLower())
            //    throw new InvalidCastException("Cannot convert " + xmlNode.Name + " into the " + type.Name);

            object obj = Activator.CreateInstance(type);

            PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            Dictionary <string, PropertyInfo>           attributes       = new Dictionary <string, PropertyInfo>();
            Dictionary <string, ICustomMappingStrategy> customStrategies = new Dictionary <string, ICustomMappingStrategy>();
            List <string> ignoreList = new List <string>();

            IEnumerable <PropertyInfo> props = type.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(PropertyMappingAttribute)));

            foreach (PropertyInfo propertyInfo in props)
            {
                PropertyMappingAttribute attr = (PropertyMappingAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(PropertyMappingAttribute));
                attributes.Add(attr.Name.ToLower(), propertyInfo);
            }

            props = type.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(CustomStrategyAttribute)));
            foreach (PropertyInfo propertyInfo in props)
            {
                CustomStrategyAttribute attr     = (CustomStrategyAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(CustomStrategyAttribute));
                ICustomMappingStrategy  strategy = (ICustomMappingStrategy)Activator.CreateInstance(attr.StrategyType);
                customStrategies.Add(propertyInfo.Name.ToLower(), strategy);
            }

            props = type.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(IgnorePropertyAttribute)));
            foreach (PropertyInfo propertyInfo in props)
            {
                ignoreList.Add(propertyInfo.Name.ToLower());
            }

            if (xmlNode.Attributes != null)
            {
                for (int i = 0; i < xmlNode.Attributes.Count; i++)
                {
                    XmlAttribute xmlAttribute   = xmlNode.Attributes[i];
                    string       attributeName  = xmlAttribute.Name.ToLower();
                    string       attributeValue = xmlAttribute.Value;

                    if (ignoreList.Contains(attributeName))
                    {
                        continue;
                    }

                    PropertyInfo propertyInfo;
                    if (attributes.TryGetValue(attributeName, out propertyInfo) == false)
                    {
                        propertyInfo = propertyInfos.Single(x => x.Name.ToLower() == attributeName);
                    }

                    object value;
                    if (customStrategies.ContainsKey(propertyInfo.Name.ToLower()))
                    {
                        ICustomMappingStrategy customMappingStrategy = customStrategies[propertyInfo.Name.ToLower()];
                        value = customMappingStrategy.Map(attributeValue, propertyInfo.PropertyType);
                    }
                    else
                    {
                        IPrimitiveMappingStrategy mappingStrategy = mappingStrategyFactory.CreatePrimitiveStrategy(propertyInfo.PropertyType);
                        value = mappingStrategy.Map(attributeValue, propertyInfo.PropertyType);
                    }
                    propertyInfo.SetValue(obj, value, null);
                }
            }

            if (xmlNode.HasChildNodes)
            {
                for (int i = 0; i < xmlNode.ChildNodes.Count; i++)
                {
                    XmlNode child = xmlNode.ChildNodes[i];
                    if (child.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }

                    string childName = child.Name.ToLower();
                    if (ignoreList.Contains(childName))
                    {
                        continue;
                    }

                    PropertyInfo propertyInfo;
                    if (attributes.TryGetValue(childName, out propertyInfo) == false)
                    {
                        propertyInfo = propertyInfos.Single(x => x.Name.ToLower() == childName);
                    }

                    if (customStrategies.ContainsKey(propertyInfo.Name.ToLower()))
                    {
                        ICustomMappingStrategy customMappingStrategy = customStrategies[propertyInfo.Name.ToLower()];
                        var value = customMappingStrategy.Map(child, propertyInfo.PropertyType);
                        propertyInfo.SetValue(obj, value, null);
                        continue;
                    }

                    Type propertyType = propertyInfo.PropertyType;
                    if (propertyType.IsPrimitive || propertyType == typeof(string) || propertyType.IsEnum)
                    {
                        IPrimitiveMappingStrategy mappingStrategy = mappingStrategyFactory.CreatePrimitiveStrategy(propertyInfo.PropertyType);
                        var value = mappingStrategy.Map(child.InnerText, propertyInfo.PropertyType);
                        propertyInfo.SetValue(obj, value, null);
                    }
                    else
                    {
                        IMappingStrategy mappingStrategy = mappingStrategyFactory.CreateComplexStrategy(propertyInfo.PropertyType);
                        var value = mappingStrategy.Map(child, propertyInfo.PropertyType, this);
                        propertyInfo.SetValue(obj, value, null);
                    }
                }
            }

            return(obj);
        }