示例#1
0
        private void DepthBuild(BuildTreeNode <CustomBuildTreeNodeConfig> buildNode, PropertiesTreeNode newNode)
        {
            // Создаём другие node дерева.
            List <PropertiesTreeNode> newNodes = new List <PropertiesTreeNode>();

            foreach (var nodePair in buildNode.ChildNodes)
            {
                //string propName = nodePair.Key;
                //if (buildNode.Config.IgnoredProperties.Contains(propName))
                //    continue;

                var newInnerNode = new PropertiesTreeNode(nodePair.Value.Property);

                // Если это поле
                if (buildNode.Config.GoDepthProperties.Contains(newInnerNode.PropertyName))
                {
                    DifferenceSearchBuilderExtensions.AutoDepthBuild(newInnerNode.PropertyType, newInnerNode);
                }
                else
                {
                    DepthBuild(nodePair.Value, newInnerNode);
                }

                newNodes.Add(newInnerNode);
            }

            newNode.InnerProperties = buildNode.Config.NeedAllProperties
                ? buildNode.PropertyType.GetProperties()
                : buildNode.Config.SelectedProperties.ToArray();
            newNode.Nodes = newNodes.ToArray();
        }
示例#2
0
        public void Build()
        {
            PropertiesTreeNode root = new PropertiesTreeNode(typeof(TSource));

            DepthBuild(_buildRootNode, root);

            PropertyTree = root;
        }
        private PropertyDifference[] GetDifferences(PropertiesTreeNode node, object firstObj, object secondObj)
        {
            List <PropertyDifference> differences = new List <PropertyDifference>();

            foreach (PropertyInfo info in node.InnerProperties)
            {
                var left  = info.GetValue(firstObj);
                var right = info.GetValue(secondObj);

                if (left == right)
                {
                    continue;
                }

                if (left == null || right == null || !left.Equals(right))
                {
                    differences.Add(new PropertyDifference
                    {
                        ClassType    = node.PropertyType,
                        PropertyType = info.PropertyType,
                        PropertyName = info.Name,
                        ValueLeft    = left,
                        ValueRight   = right
                    });
                }
            }

            foreach (var childNode in node.Nodes)
            {
                var left  = childNode.Property.GetValue(firstObj);
                var right = childNode.Property.GetValue(secondObj);

                if (left == right)
                {
                    continue;
                }

                if (left == null || right == null)
                {
                    differences.Add(new PropertyDifference
                    {
                        ClassType    = node.PropertyType,
                        PropertyType = childNode.PropertyType,
                        PropertyName = childNode.PropertyName,
                        ValueLeft    = left,
                        ValueRight   = right
                    });
                    continue;
                }

                var newDiffs = GetDifferences(childNode, left, right);
                differences.AddRange(newDiffs);
            }

            return(differences.ToArray());
        }
        public PropertyDifference[] GetCustomDifferences <T>(T firstObj, T secondObj)
        {
            Type type = typeof(T);

            if (!_customBuildersMap.ContainsKey(type))
            {
                throw new KeyNotFoundException($"Для типа {type} не зарегистрирован builder");
            }

            PropertiesTreeNode tree = _customBuildersMap[type].PropertyTree;

            return(GetDifferences(tree, firstObj, secondObj));
        }
        public PropertyDifference[] GetAutoDifferences <T>(T firstObj, T secondObj)
        {
            IAutoDifferenceSearchBuilder <T> searchBuilder = AutoBuilder <T>();

            if (searchBuilder.PropertyTree == null)
            {
                searchBuilder.Build();
            }

            PropertiesTreeNode tree = searchBuilder.PropertyTree;

            return(GetDifferences(tree, firstObj, secondObj));
        }
示例#6
0
        private void DepthBuild(BuildTreeNode <AutoBuildTreeNodeConfig> buildNode, PropertiesTreeNode newNode)
        {
            PropertyInfo[] allTypeProperties = buildNode.PropertyType.GetProperties();

            // Исключаем все игнорируемые поля.
            PropertyInfo[] neededProperties = allTypeProperties
                                              .Where(info => !buildNode.Config.IgnoredProperties.Contains(info.Name)).ToArray();

            // Создаём другие node дерева.
            List <PropertiesTreeNode> newNodes = new List <PropertiesTreeNode>();

            foreach (var info in neededProperties)
            {
                // Если в build версии дерева есть node, тогда проходим по его правилам.
                if (buildNode.ChildNodes.ContainsKey(info.Name))
                {
                    if (buildNode.ChildNodes[info.Name].Config.IsDeadEnd)
                    {
                        continue;
                    }

                    var newInnerNode = new PropertiesTreeNode(info);
                    DepthBuild(buildNode.ChildNodes[info.Name], newInnerNode);
                    newNodes.Add(newInnerNode);
                }
                // Если в build версии дерева нету node, тогда запускаем полностью рефлексивный обход.
                else if (!info.PropertyType.IsSimple())
                {
                    var newInnerNode = new PropertiesTreeNode(info);
                    DifferenceSearchBuilderExtensions.AutoDepthBuild(info.PropertyType, newInnerNode);
                    newNodes.Add(newInnerNode);
                }
            }

            newNode.InnerProperties = neededProperties;
            newNode.Nodes           = newNodes.ToArray();
        }
示例#7
0
        /// <summary>
        /// Запускает бесконтрольный рекурсивный билдер дерева.
        /// </summary>
        /// <param name="type">Тип текущей ветки дерева.</param>
        /// <param name="newNode">Ветка дерева.</param>
        /// <remarks>
        /// TODO Надо добавить Hashset&ltType&gt чтобы отслеживать рекурсии и на них реагировать эксепшеном.
        /// </remarks>
        public static void AutoDepthBuild(Type type, PropertiesTreeNode newNode)
        {
            PropertyInfo[] allTypeProperties = type.GetProperties();

            if (allTypeProperties.Any(x => x.PropertyType == type))
            {
                throw new ArgumentException($"Property type matched class type. Stack overflow is inevitable. Type: '{type}'");
            }

            List <PropertiesTreeNode> newNodes = new List <PropertiesTreeNode>();

            foreach (var info in allTypeProperties)
            {
                if (!info.PropertyType.IsSimple())
                {
                    var newInnerNode = new PropertiesTreeNode(info);
                    AutoDepthBuild(info.PropertyType, newInnerNode);
                    newNodes.Add(newInnerNode);
                }
            }

            newNode.InnerProperties = allTypeProperties;
            newNode.Nodes           = newNodes.ToArray();
        }
示例#8
0
 public AutoDifferenceSearchBuilder()
 {
     PropertyTree   = null;
     _buildRootNode = new BuildTreeNode <AutoBuildTreeNodeConfig>(typeof(TSource));
 }