private void FillInstance(PropertyInfo[] props, ParamObject metaObj, object instance) { foreach (var propertyInfo in props) { bool destIsCollection = typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType) && propertyInfo.PropertyType != typeof(string); var metap = metaObj.Properties.FirstOrDefault(p => p.PropertyName == propertyInfo.Name); if (metap == null) { continue; } if (metap.PropertyType == PropertyType.ValueType && !destIsCollection) { propertyInfo.SetValue(instance, ((string)metap.Value).ChangeType(propertyInfo.PropertyType), null); } else if (metap.PropertyType == PropertyType.ParamObject && propertyInfo.PropertyType.IsClass) { var rinstance = Activator.CreateInstance(propertyInfo.PropertyType); var rprops = propertyInfo.PropertyType.GetProperties(DefaultBindingFlags); var rmetaObj = (ParamObject)metap.Value; FillInstance(rprops, rmetaObj, rinstance); propertyInfo.SetValue(instance, rinstance, null); } else if (destIsCollection) { propertyInfo.SetValue(instance, ResolveCollection(propertyInfo, metap.Value), null); } else { throw new AmbiguousMatchException("A no collection property may have multiple values... or something like that."); } } }
public ParamObject Parse(NameValueCollection queryString) { var result = new ParamObject(null); var keys = queryString.AllKeys; if (keys != null && keys.Length > 0) { foreach (var key in keys) { var parts = key.Split('.'); if (parts.Length == 1) { result.Properties.Add(NewValueProp(key, queryString.GetValues(key))); } else { ParamObject owner = result; foreach (var part in parts.Take(parts.Length - 1)) { var newProp = new Property(part, PropertyType.ParamObject); var prop = owner.Properties.FirstOrDefault(x => x.Equals(newProp)) ?? newProp; owner.Properties.Add(prop); if (prop.Value == null) { prop.Value = new ParamObject(prop); } owner = (ParamObject)prop.Value; } owner.Properties.Add(NewValueProp(parts[parts.Length - 1], queryString.GetValues(key))); } } } return(result); }