/// <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)); }
/// <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); }
/// <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); }