Пример #1
0
        private void Initialize()
        {
            foreach (var typeId in typesService.GetRegisteredTypes())
            {
                if (!typesService.IsScalarType(typeId))
                {
                    var type = typesService.GetTypeFromId(typeId);

                    var rule = new TypeMergeRule();

                    Type collectionType = null;
                    Type dictionaryType = null;

                    if (!Utils.IsCollectionType(type, ref collectionType) &&
                        !Utils.IsDictionaryType(type, ref dictionaryType))
                    {
                        var attributes = type.GetCustomAttributes(typeof(ConcurrentAttribute), true);

                        if (attributes.Length == 1)
                        {
                            rule.IsConcurrent        = true;
                            rule.IsStaticConcurrency = ((ConcurrentAttribute)attributes[0]).Behavior == ConcurrentBehavior.Static;
                            if (!rule.IsStaticConcurrency)
                            {
                                rule.DynamicResolverType = ((ConcurrentAttribute)attributes[0]).Resolver;
                            }
                            else
                            {
                                foreach (var edge in typesService.GetTypeEdges(typeId))
                                {
                                    if (edge.Data.Semantic == Graph.EdgeType.Property)
                                    {
                                        var memberId = edge.ToNodeId;
                                        //var memberTypeId = typesService.GetMemberTypeId(memberId);
                                        var memberName = typesService.GetMemberName(typeId, memberId);

                                        PropertyInfo propertyInfo = FindPropertyInfo(type, memberName);

                                        bool isOverride = propertyInfo.GetCustomAttributes(typeof(OverrideAttribute), false).Length == 1;

                                        rule.IsMemberOverride.Add(memberId, isOverride);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        rule.IsConcurrent        = true;
                        rule.IsStaticConcurrency = true;
                    }

                    // Add rule for the type in cache
                    typeMergeRules.Add(typeId, rule);
                }
            }
        }
Пример #2
0
        private static void LogObject(Guid nodeId, Node <Guid, object, EdgeData> node, INodeProvider <Guid, object, EdgeData> nodes, INodeProvider <Guid, object, EdgeData> changes, int tabLevel, Hashtable visited, TypesService typesService)
        {
            var typeId   = typesService.GetInstanceTypeId(node);
            var typeName = typesService.GetTypeFromId(typeId).Name;

            Debug.WriteLine(LogTabs(tabLevel) + nodeId + "(" + typeName + ")");
            Debug.WriteLine(LogTabs(tabLevel) + "Previous=" + node.Previous);

            foreach (var value in node.Values)
            {
                Debug.WriteLine(LogTabs(tabLevel) + typesService.GetMemberName(typeId, value.Key) + "=" + value.Value);
            }

            foreach (var edge in node.Edges)
            {
                if (edge.Value.Data.Semantic == EdgeType.Property)
                {
                    Debug.WriteLine(LogTabs(tabLevel) + typesService.GetMemberName(typeId, (Guid)edge.Value.Data.Data) + "=");
                    LogNodesRecursive(edge.Value.ToNodeId, nodes, changes, tabLevel + 1, visited, typesService);
                }
            }
        }
Пример #3
0
        private void MergeObjectsStatic(Guid nodeId, Guid typeId, Node <Guid, object, EdgeData> originalNode, Node <Guid, object, EdgeData> changedNode, Node <Guid, object, EdgeData> node, MergeRecursiveDelegate mergeRecursive, InsertRecursiveDelegate insertRecursive, RecursiveResolutionParameters parameters)
        {
            // Consolidate the values
            foreach (var item in originalNode.Values)
            {
                // Value was changed compared to previous version
                if (!changedNode.Values[item.Key].Equals(item.Value))
                {
                    // Try setting value in the node, if it is still the same
                    if (node.Values[item.Key].Equals(item.Value))
                    {
                        node.Values[item.Key] = changedNode.Values[item.Key];
                    }
                    else
                    {
                        if (objectAttributeProvider.IsMemberOverride(typeId, item.Key))
                        {
                            // Override with changed value
                            node.Values[item.Key] = changedNode.Values[item.Key];
                        }
                        else
                        {
                            throw new ConcurrentModificationException("Concurrent modification of scalar value not allowed in type:" + typesService.GetTypeFromId(typeId).ToString() + " for member " + typesService.GetMemberName(typeId, item.Key));
                        }
                    }
                }
            }

            // Consolidate the edges
            foreach (var edge in originalNode.Edges)
            {
                // Value was changed compared to previous version
                if (!changedNode.Edges[edge.Key].ToNodeId.Equals(edge.Value.ToNodeId))
                {
                    // Was member set to override?
                    bool isOverride = objectAttributeProvider.IsMemberOverride(typeId, (Guid)edge.Key.Data);

                    // Try setting value in the node, if it is still the same or if override is set
                    if (node.Edges[edge.Key].ToNodeId.Equals(edge.Value.ToNodeId) || isOverride)
                    {
                        Guid newReference        = changedNode.Edges[edge.Key].ToNodeId;
                        Guid newReferenceUpdated = Guid.Empty;

                        // Is there an intermediate change?
                        if (parameters.IntermediateChanges.TryGetValue(newReference, out newReferenceUpdated))
                        {
                            // Set edge to node from the changed node
                            node.SetEdgeToNode(edge.Value.Data, newReferenceUpdated);
                            // See about the new object
                            mergeRecursive(newReferenceUpdated, parameters);
                        }
                        else
                        {
                            NodeState nodeState = NodeState.None;
                            parameters.ChangeSet.NodeStates.TryGetValue(newReference, out nodeState);

                            // If changed node is a new node go into the changed node recursion
                            if (nodeState == NodeState.Created)
                            {
                                // Set the new reference
                                node.SetEdgeToNode(edge.Value.Data, newReference);
                                // Insert the new nodes
                                insertRecursive(newReference, parameters);
                            }
                            else
                            {
                                // Set the new reference
                                node.SetEdgeToNode(edge.Value.Data, newReference);
                                // Follow the new reference and see changes
                                mergeRecursive(newReference, parameters);
                            }
                        }
                    }
                    else
                    {
                        throw new ConcurrentModificationException("Concurrent modification of referenced item not allowed in type:" + typesService.GetTypeFromId(typeId).ToString() + " for member " + typesService.GetMemberName(typeId, (Guid)edge.Key.Data));
                    }
                }
                else
                {
                    mergeRecursive(node.Edges[edge.Key].ToNodeId, parameters);
                }
            }
        }