private ObjectRepresentation CreateChildObjectRepresentation(object item, object parent = null, Action removeAction = null, Func <object, object, object> getterFunc = null) { if (EntityExistsInRepository(item)) { var objectRepresentation = _data.SingleOrDefault(x => x.Entity == item); if (!objectRepresentation.Parents.ContainsKey(parent)) { objectRepresentation.Parents.Add(parent, new Accessor(removeAction, getterFunc)); } return(objectRepresentation); } else { var objectRepresentation = new ObjectRepresentation { Entity = item, Parents = new Dictionary <object, Accessor> { { parent, new Accessor(removeAction, getterFunc) } } }; _data.Add(objectRepresentation); objectRepresentation.RelatedEntities = AddRelatedObjects(item); return(objectRepresentation); } }
private void UpdateExistingRepresentations(ObjectRepresentation rep) { var type = rep.Entity.GetType(); var nonPrimitivePropertiesFromObject = type.GetProperties().Where(x => !x.PropertyType.GetTypeInfo().IsPrimitive).ToList(); var typesCurrentlyStored = rep.RelatedEntities.Select(x => x.Entity.GetType()).ToList(); List <object> referencedProperties = new List <object>(); foreach (var info in nonPrimitivePropertiesFromObject) { if (typesCurrentlyStored.Contains(info.PropertyType.ToSingleType())) { if (info.PropertyType.IsEnumerable()) { IEnumerable values = (IEnumerable)info.GetValue(rep.Entity, null); referencedProperties.AddRange(values.Cast <object>()); } else { referencedProperties.Add(info.GetValue(rep.Entity, null)); } } } foreach (var data in rep.RelatedEntities.Where(x => typesCurrentlyStored.Contains(x.Entity.GetType()))) { if (!referencedProperties.Contains(data.Entity)) { continue; } var collectionType = typeof(ICollection <>).MakeGenericType(type); var propertiesThatReferToRepresentation = data.Entity.GetType() .GetProperties() .Where(x => x.PropertyType == type || x.PropertyType.IsAssignableFrom(collectionType)); var addMethod = collectionType.GetMethod("Add"); var propertyInfos = propertiesThatReferToRepresentation.ToList(); if (!propertyInfos.Any() || propertyInfos.Count() > 1) { return; } var referencingProperty = propertyInfos.Single(); if (referencingProperty.PropertyType.IsAssignableFrom(collectionType)) { var collection = referencingProperty.GetValue(data.Entity, null); if (collection == null) { var listType = typeof(List <>).MakeGenericType(type); referencingProperty.SetValue(data.Entity, Activator.CreateInstance(listType), null); collection = referencingProperty.GetValue(data.Entity, null); } addMethod.Invoke(collection, new[] { rep.Entity }); } else { referencingProperty.SetValue(data.Entity, rep.Entity, null); } } }
internal void Add <T>(T item) where T : class { if (EntityExistsInRepository(item)) { return; } var rep = new ObjectRepresentation { Entity = item }; _data.Add(rep); rep.RelatedEntities = AddRelatedObjects(item); UpdateExistingRepresentations(rep); }
private IEnumerable <ObjectRepresentation> GetSingularRelationships <T>(T item) { List <ObjectRepresentation> reps = new List <ObjectRepresentation>(); var properties = item.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.PropertyType.GetTypeInfo().IsClass && !typeof(IEnumerable).IsAssignableFrom(x.PropertyType) && x.GetValue(item, null) != null); foreach (var propertyInfo in properties) { var child = propertyInfo.GetValue(item, null); Func <object, object, object> getterFunc = (parent, kid) => propertyInfo.GetValue(parent, null); Action removeAction = () => propertyInfo.SetValue(item, null, null); ObjectRepresentation childTypeRepresentation = CreateChildObjectRepresentation(child, item, removeAction, getterFunc); reps.Add(childTypeRepresentation); } return(reps); }
private IEnumerable <ObjectRepresentation> GetMultipleRelationships <T>(T item) { List <ObjectRepresentation> reps = new List <ObjectRepresentation>(); var properties = item.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(x.PropertyType) && x.GetValue(item, null) != null); foreach (var propertyInfo in properties) { var childCollection = (IEnumerable)propertyInfo.GetValue(item, null); foreach (var child in childCollection) { var removeAction = CreateRemoveFromCollectionAction(propertyInfo, item, child); var getterFunc = CreateGetterFromCollectionFunc(propertyInfo, child); ObjectRepresentation childTypeRepresentation = CreateChildObjectRepresentation(child, item, removeAction, getterFunc); reps.Add(childTypeRepresentation); } } return(reps); }