/// <summary> /// Generates an array of ProperyMeta class from a domain class /// </summary> /// <param name="type"></param> /// <returns></returns> public PropertyMeta[] GetPropertyDefs(Type type) { PropertyMeta[] defs; bool found = PROPERTY_DEF_MAP.TryGetValue(type, out defs); if (found) { return(defs); } lock (this) { found = PROPERTY_DEF_MAP.TryGetValue(type, out defs); if (found) { return(defs); } PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); defs = new PropertyMeta[properties.Length]; for (int i = 0; i < properties.Length; i++) { defs[i] = this.propertyMetaFactory.Create(properties[i]); } PROPERTY_DEF_MAP.Add(type, defs); } return(defs); }
private Dtobase Filter(Dtobase item, Type type, byte level) { try { if (null == item) { return(null); } Dtobase dto = (Dtobase)Activator.CreateInstance(type); PropertyMeta[] properties = this.context.GetPropertyDefs(type); for (int i = 0; i < properties.Length; i++) { PropertyMeta property = properties[i]; if (!property.Valid || !property.HasLevel(level)) { continue; } Object value = property.Read(item); if (PropertyMeta.ClassType.Value == property.PropertyClassType || PropertyMeta.ClassType.CustomType == property.PropertyClassType || PropertyMeta.ClassType.CustomTypeCollection == property.PropertyClassType) { property.Write(dto, value); } else if (PropertyMeta.ClassType.Class == property.PropertyClassType) { byte nestedLevel = property.DtoNestedLevel; if (level != property.DtoLevel) { nestedLevel = (byte)(nestedLevel + level - property.DtoLevel); } property.Write(dto, this.Filter((Dtobase)value, property.PropertyClass, nestedLevel)); } else if (PropertyMeta.ClassType.Collection == property.PropertyClassType) { byte nestedLevel = property.DtoNestedLevel; if (level != property.DtoLevel) { nestedLevel = (byte)(nestedLevel + level - property.DtoLevel); } property.Write(dto, this.FilterList((IEnumerable)value, property.InnerGenericClass, nestedLevel)); } } return(dto); } catch (Exception ex) { throw new Exception( "Filtering failed. Type:'" + item.GetType().Name + "'. Level:'" + level + "'", ex); } }
private void MapTo(Dtobase source, Dtobase dest, Type type) { if (null == source) { return; } try { PropertyMeta[] properties = this.context.GetPropertyDefs(type); for (int i = 0; i < properties.Length; i++) { PropertyMeta property = properties[i]; if (!property.Valid || !property.IsAssigned(source)) { continue; } Object sourceValue = property.Read(source); Object destValue = property.Read(dest); if (null == sourceValue || null == destValue || PropertyMeta.ClassType.Value == property.PropertyClassType || PropertyMeta.ClassType.CustomType == property.PropertyClassType || PropertyMeta.ClassType.CustomTypeCollection == property.PropertyClassType) { property.Write(dest, sourceValue); } else if (PropertyMeta.ClassType.Class == property.PropertyClassType) { if (object.Equals(sourceValue, destValue)) { this.MapTo((Dtobase)sourceValue, (Dtobase)destValue, sourceValue.GetType()); } else { property.Write(dest, sourceValue); } } else if (PropertyMeta.ClassType.Collection == property.PropertyClassType) { IEnumerable destList = (IEnumerable)destValue; IEnumerable sourceList = (IEnumerable)sourceValue; this.MapToCollection(sourceList, destList, source); } } } catch (Exception ex) { throw new Exception( "Mapping failed from '" + source.GetType().Name + "' to '" + dest.GetType().Name + "'", ex); } }
private object ParseValue(JToken node, PropertyMeta propertyDef) { string text = node.Value <string>(); if (string.IsNullOrEmpty(text)) { return(null); } return(propertyDef.Parser.ParseTextValue(propertyDef.PropertyClass, text)); }
/// <summary> /// Creates an instance of PropertyMeta class based on property descriptor /// </summary> /// <param name="descriptor">property descriptor</param> /// <returns>instance of PropertyMeta class</returns> public PropertyMeta Create(PropertyInfo descriptor) { PropertyMeta meta = new PropertyMeta(descriptor); DtoAttribute annotation = descriptor.GetCustomAttribute <DtoAttribute>(); if (null != annotation) { meta.Valid = true; meta.DtoLevel = annotation.Value; meta.DtoNestedLevel = annotation.Nested; meta.DtoCustomType = annotation.IsCustomType; meta.DtoDynamic = annotation.Dynamic; meta.PropertyClassType = this.BuildClassType(meta.PropertyClass, annotation); meta.InnerGenericClass = this.BuildNestedGenericClass(meta.PropertyClass); meta.Parser = this.context.BuildParser(meta.Name, meta.PropertyClass, meta.PropertyClassType, annotation); } return(meta); }
private void Map(Dtobase source, Type type) { PropertyMeta property = null; try { PropertyMeta[] properties = this.context.GetPropertyDefs(type); for (int i = 0; i < properties.Length; i++) { property = properties[i]; if (!property.Valid) { continue; } object sourceValue = property.Read(source); if (null != sourceValue) { if (PropertyMeta.ClassType.Class == property.PropertyClassType) { this.Map((Dtobase)sourceValue, property.PropertyClass); } else if (PropertyMeta.ClassType.Collection == property.PropertyClassType) { IEnumerable sourceSet = (IEnumerable)sourceValue; foreach (object item in sourceSet) { this.Map((Dtobase)item, property.InnerGenericClass); if (item is IChild) { (item as IChild).ConnectToParent(source); } } } } } } catch (Exception ex) { throw new Exception("Mapping failed. Type:'" + source.GetType().Name + "'. Name:'" + property.Name + "'", ex); } }
/// <summary> /// Parses JSON data into domain object /// </summary> /// <param name="node">JSON tree</param> /// <param name="type">domain object type</param> /// <returns>parsed domain object instance</returns> public object Parse(JToken node, Type type) { try { Dtobase dto = (Dtobase)Activator.CreateInstance(type); if (!node.HasValues) { return(dto); } PropertyMeta[] properties = this.context.GetPropertyDefs(type); for (int i = 0; i < properties.Length; i++) { PropertyMeta propertyDef = properties[i]; if (!propertyDef.Valid) { continue; } JToken propertyValue = node[propertyDef.Name]; if (null != propertyValue) { try { if (PropertyMeta.ClassType.Value == propertyDef.PropertyClassType) { dto.AddAssignedField(propertyDef.Name); propertyDef.Write(dto, this.ParseValue(propertyValue, propertyDef)); } else if (PropertyMeta.ClassType.Class == propertyDef.PropertyClassType || PropertyMeta.ClassType.CustomType == propertyDef.PropertyClassType) { dto.AddAssignedField(propertyDef.Name); propertyDef.Write(dto, this.Parse(propertyValue, propertyDef.PropertyClass)); } else if (PropertyMeta.ClassType.Collection == propertyDef.PropertyClassType || PropertyMeta.ClassType.CustomTypeCollection == propertyDef.PropertyClassType) { IList list = (IList)this.context.BuildList(propertyDef.InnerGenericClass); foreach (JToken item in propertyValue) { list.Add(this.Parse(item, propertyDef.InnerGenericClass)); } propertyDef.Write(dto, list); dto.AddAssignedField(propertyDef.Name); } } catch { dto.AddWrongField(propertyDef.Name); } } } return(dto); } catch (Exception ex) { throw new Exception("JSON parsing failed", ex); } }