Beispiel #1
0
        /// <summary>
        /// Parses all relationships from <paramref name="type" /> to other models in the resource resourceGraphs by constructing RelationshipProxies .
        /// </summary>
        /// <param name="type">
        /// The type to parse
        /// </param>
        private void RegisterRelationshipProxies(RightType type)
        {
            foreach (RelationshipAttribute attr in _resourceGraph.GetRelationships(type))
            {
                if (!attr.CanInclude)
                {
                    continue;
                }

                if (!_relationshipProxies.TryGetValue(attr, out _))
                {
                    RightType rightType         = GetRightTypeFromRelationship(attr);
                    bool      isContextRelation = false;
                    ISet <RelationshipAttribute> relationshipsToUpdate = _targetedFields.Relationships;

                    if (relationshipsToUpdate != null)
                    {
                        isContextRelation = relationshipsToUpdate.Contains(attr);
                    }

                    var proxy = new RelationshipProxy(attr, rightType, isContextRelation);
                    _relationshipProxies[attr] = proxy;
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Create a next layer from any previous layer
        /// </summary>
        /// <returns>
        /// The next layer.
        /// </returns>
        /// <param name="nodes">Nodes.</param>
        public IEnumerable <IResourceNode> CreateNextLayer(IEnumerable <IResourceNode> nodes)
        {
            // first extract resources by parsing populated relationships in the resources
            // of previous layer
            (Dictionary <RelationshipProxy, List <IIdentifiable> > lefts, Dictionary <RelationshipProxy, List <IIdentifiable> > rights) = ExtractResources(nodes);

            // group them conveniently so we can make ChildNodes of them:
            // there might be several relationship attributes in rights dictionary
            // that point to the same right type.
            IDictionary <RightType, List <KeyValuePair <RelationshipProxy, List <IIdentifiable> > > > leftsGrouped = GroupByRightTypeOfRelationship(lefts);

            // convert the groups into child nodes
            List <IResourceNode> nextNodes = leftsGrouped.Select(entry =>
            {
                RightType nextNodeType = entry.Key;
                RegisterRelationshipProxies(nextNodeType);

                var populatedRelationships = new List <RelationshipProxy>();

                List <IRelationshipGroup> relationshipsToPreviousLayer = entry.Value.Select(grouped =>
                {
                    RelationshipProxy proxy = grouped.Key;
                    populatedRelationships.AddRange(GetPopulatedRelationships(nextNodeType, rights[proxy]));
                    return(CreateRelationshipGroupInstance(nextNodeType, proxy, grouped.Value, rights[proxy]));
                }).ToList();

                return(CreateNodeInstance(nextNodeType, populatedRelationships.ToArray(), relationshipsToPreviousLayer));
            }).ToList();

            return(nextNodes);
        }
Beispiel #3
0
        private void Reassign(IEnumerable <IIdentifiable> leftResources, RelationshipProxy proxy, HashSet <TResource> unique)
        {
            foreach (IIdentifiable left in leftResources)
            {
                var currentValue = proxy.GetValue(left);

                if (currentValue is IEnumerable <IIdentifiable> relationshipCollection)
                {
                    var         intersection    = relationshipCollection.Intersect(unique, _comparer);
                    IEnumerable typedCollection =
                        TypeHelper.CopyToTypedCollection(intersection, relationshipCollection.GetType());
                    proxy.SetValue(left, typedCollection);
                }
                else if (currentValue is IIdentifiable relationshipSingle)
                {
                    if (!unique.Intersect(new HashSet <IIdentifiable> {
                        relationshipSingle
                    }, _comparer).Any())
                    {
                        proxy.SetValue(left, null);
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Reflective helper method to create an instance of <see cref="RelationshipGroup{TRight}" />;
        /// </summary>
        private IRelationshipGroup CreateRelationshipGroupInstance(RightType thisLayerType, RelationshipProxy proxy, List <IIdentifiable> leftResources,
                                                                   List <IIdentifiable> rightResources)
        {
            IEnumerable rightResourceSet = CollectionConverter.CopyToHashSet(rightResources, thisLayerType);

            return((IRelationshipGroup)ObjectFactory.CreateInstanceOfOpenType(typeof(RelationshipGroup <>), thisLayerType, proxy,
                                                                              new HashSet <IIdentifiable>(leftResources), rightResourceSet));
        }
Beispiel #5
0
        private void AddToRelationshipGroup(Dictionary <RelationshipProxy, List <IIdentifiable> > target, RelationshipProxy proxy,
                                            IEnumerable <IIdentifiable> newResources)
        {
            if (!target.TryGetValue(proxy, out List <IIdentifiable> resources))
            {
                resources     = new List <IIdentifiable>();
                target[proxy] = resources;
            }

            resources.AddRange(newResources);
        }
Beispiel #6
0
 public RelationshipGroup(RelationshipProxy proxy, HashSet <IIdentifiable> leftResources, HashSet <TRight> rightResources)
 {
     Proxy          = proxy;
     LeftResources  = leftResources;
     RightResources = rightResources;
 }
Beispiel #7
0
        /// <summary>
        /// Reflective helper method to create an instance of <see cref="RelationshipGroup{TRight}"/>;
        /// </summary>
        private IRelationshipGroup CreateRelationshipGroupInstance(Type thisLayerType, RelationshipProxy proxy, List <IIdentifiable> leftResources, List <IIdentifiable> rightResources)
        {
            var rightResourcesHashed = TypeHelper.CreateInstanceOfOpenType(typeof(HashSet <>), thisLayerType, TypeHelper.CopyToList(rightResources, thisLayerType));

            return((IRelationshipGroup)TypeHelper.CreateInstanceOfOpenType(typeof(RelationshipGroup <>),
                                                                           thisLayerType, proxy, new HashSet <IIdentifiable>(leftResources), rightResourcesHashed));
        }