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.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);
                }
            }
        }
Ejemplo n.º 3
0
        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);
        }
        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.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);
        }