private void AttachNodeToParent(DataSerializerParentDetails parentDetails, object instance) { if (parentDetails == null) return; var xomChildDetails = parentDetails.ParentXomNode .Children .First(x => x.AvailableNodes.Any(y => y.Key == parentDetails.ChildNodeName)); var parentProperty = parentDetails.ParentObject .GetType() .GetProperties() .First(x => x.Name == xomChildDetails.PropertyName); // If the parent property is a collection, instantiate it if it hasn't been already, // then add this element to the collection var propertyType = parentProperty.PropertyType; if (propertyType.IsGenericType && TypeIsCollection(propertyType)) { var collection = parentProperty.GetValue(parentDetails.ParentObject); if (collection == null) { collection = Activator.CreateInstance(propertyType); parentProperty.SetValue(parentDetails.ParentObject, collection); } // Since we know this inherits from ICollection<>, find the Add method var addMethod = collection.GetType() .GetMethods() .Where(x => x.Name == "Add") .Where(x => x.GetParameters().Length == 1) .Where(x => x.GetParameters()[0].ParameterType == propertyType.GetGenericArguments()[0]) .First(); addMethod.Invoke(collection, new[] {instance}); } else { parentProperty.SetValue(parentDetails.ParentObject, instance); } }
private object GenerateXmlObjectForNodeData(XomNodeData data, DataSerializerParentDetails parentDetails) { if (data == null) throw new ArgumentNullException("data"); if (data.NodeType == null) throw new ArgumentException("Data object has a null xom node type"); if (data.NodeType.Type == null) throw new ArgumentException("Data object's xom node type has a null Type value"); var instance = Activator.CreateInstance(data.NodeType.Type); AttachAttributeDataToXmlObject(data, instance); // Attach the instance to the parent AttachNodeToParent(parentDetails, instance); // Serialize children if (data.ChildNodes != null) { foreach (var childDataPair in data.ChildNodes) { var details = new DataSerializerParentDetails { ParentObject = instance, ParentXomNode = data.NodeType, ChildNodeName = childDataPair.Key }; GenerateXmlObjectForNodeData(childDataPair.Value, details); } } return instance; }