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)); }
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); }
/// <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()); }
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); } }
/// <summary> /// Resolve a relation reference /// </summary> public Resource ResolveReference(ResourceRelationAccessor relation) { return(relation.ReferenceId > 0 ? _graph.Get(relation.ReferenceId) : ResourceLookup[relation.ReferenceEntity]); }
/// <summary> /// Reusable method for resolver delegate /// </summary> /// <param name="relation"></param> /// <returns></returns> private Resource ResolveRefernceWithGraph(ResourceRelationAccessor relation) => Graph.Get(relation.ReferenceId);