Example #1
0
        private static bool PropertyMatchesRelation(PropertyInfo property, ResourceRelationAccessor relation, Resource instance)
        {
            var att = property.GetCustomAttribute <ResourceReferenceAttribute>();

            return(att.Role == relation.Role && att.RelationType == relation.RelationType && att.Name == relation.Name &&
                   property.PropertyType.IsInstanceOfType(instance));
        }
Example #2
0
        public bool Destroy(IResource resource, bool permanent)
        {
            var instance = (Resource)resource;

            ((IPlugin)resource).Stop();

            // Load entity and relations to disconnect resource and remove from database
            using (var uow = UowFactory.Create())
            {
                var resourceRepository = uow.GetRepository <IResourceEntityRepository>();
                var relationRepository = uow.GetRepository <IResourceRelationRepository>();

                // Fetch entity and relations
                // Update properties on the references and get rid of relation entities
                var entity    = resourceRepository.GetByKey(instance.Id);
                var relations = ResourceRelationAccessor.FromEntity(uow, entity);
                foreach (var relation in relations)
                {
                    var reference = Graph.Get(relation.ReferenceId);

                    ResourceLinker.RemoveLinking(resource, reference);

                    if (permanent)
                    {
                        relationRepository.Remove(relation.Entity);
                    }
                }

                resourceRepository.Remove(entity, permanent);

                uow.SaveChanges();
            }

            // Unregister from all events to avoid memory leaks
            UnregisterEvents(instance);

            // Remove from internal collections
            var removed = Graph.Remove(instance);

            // Notify listeners about the removal of the resource
            if (removed && instance is IPublicResource publicResource)
            {
                RaiseResourceRemoved(publicResource);
            }

            // Destroy the object
            TypeController.Destroy(instance);

            return(removed);
        }
Example #3
0
        /// <inheritdoc />
        public IReadOnlyList <Resource> SaveSingleCollection(IUnitOfWork uow, Resource instance, PropertyInfo property)
        {
            var entity    = uow.GetEntity <ResourceEntity>(instance);
            var relations = ResourceRelationAccessor.FromEntity(uow, entity);

            var context     = new ReferenceSaverContext(uow, Graph, instance, entity);
            var matches     = MatchingRelations(relations, property);
            var typeMatches = TypeFilter(matches, property, context.ResolveReference).ToList();
            var created     = UpdateCollectionReference(context, entity, instance, property, typeMatches);

            foreach (var resource in created)
            {
                SaveReferences(context, resource);
            }

            return(context.EntityCache.Keys.Where(i => i.Id == 0).ToList());
        }
Example #4
0
        private void SaveReferences(ReferenceSaverContext context, Resource instance)
        {
            var entity = GetOrCreateEntity(context, instance);

            var relations = ResourceRelationAccessor.FromEntity(context.UnitOfWork, entity)
                            .Union(ResourceRelationAccessor.FromQueryable(context.CreatedRelations.AsQueryable(), entity))
                            .ToList();

            var createdResources = new List <Resource>();

            foreach (var referenceProperty in ReferenceProperties(instance.GetType(), false))
            {
                var matches     = MatchingRelations(relations, referenceProperty);
                var typeMatches = TypeFilter(matches, referenceProperty, context.ResolveReference).ToList();
                if (typeof(IEnumerable <IResource>).IsAssignableFrom(referenceProperty.PropertyType))
                {
                    // Save a collection reference
                    var created = UpdateCollectionReference(context, entity, instance, referenceProperty, typeMatches);
                    createdResources.AddRange(created);
                }
                else
                {
                    // Save a single reference
                    var createdResource = UpdateSingleReference(context, entity, instance, referenceProperty, typeMatches);
                    if (createdResource != null)
                    {
                        createdResources.Add(createdResource);
                    }
                }
            }

            // Recursively save references for new resources
            foreach (var resource in createdResources)
            {
                SaveReferences(context, resource);
            }
        }
Example #5
0
 /// <summary>
 /// Resolve a relation reference
 /// </summary>
 public Resource ResolveReference(ResourceRelationAccessor relation)
 {
     return(relation.ReferenceId > 0 ? _graph.Get(relation.ReferenceId) : ResourceLookup[relation.ReferenceEntity]);
 }
Example #6
0
 /// <summary>
 /// Reusable method for resolver delegate
 /// </summary>
 /// <param name="relation"></param>
 /// <returns></returns>
 private Resource ResolveRefernceWithGraph(ResourceRelationAccessor relation) => Graph.Get(relation.ReferenceId);