Beispiel #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();
        }
Beispiel #2
0
        /// <summary>
        /// Обрабатывает выражение и возвращает callback.
        /// </summary>
        /// <typeparam name="TSource">Тип сущности, для которого осуществляется поиск.</typeparam>
        /// <typeparam name="TProp">Тип поля, по которому осуществляется поиск</typeparam>
        /// <typeparam name="TBuildTreeNodeConfig">Тип конфига билдера дерева.</typeparam>
        /// <param name="rootNode">Корневой node билдера дерева.</param>
        /// <param name="expression">Добавляемое выражение.</param>
        /// <param name="callback">Callback-функция.</param>
        /// <param name="isNeedParentNode">Указывает, нужно ли возвращать в callback child или parent node. [По умолчанию выбирается child]</param>
        public static void AddExpressionToTree <TSource, TProp, TBuildTreeNodeConfig>(
            this BuildTreeNode <TBuildTreeNodeConfig> rootNode,
            Expression <Func <TSource, TProp> > expression,
            Action <BuildTreeNode <TBuildTreeNodeConfig>, PropertyInfo> callback,
            bool isNeedParentNode = false)
            where TBuildTreeNodeConfig : BuildTreeNodeConfig, new()
        {
            Stack <PropertyInfo> propertiesPath = new Stack <PropertyInfo>();

            // Записываем весь путь в стек.
            MemberExpression currentStep = expression.Body as MemberExpression;

            if (currentStep != null)
            {
                while (currentStep is MemberExpression)
                {
                    if (!(currentStep.Member is PropertyInfo))
                    {
                        continue;
                    }
                    propertiesPath.Push(currentStep.Member as PropertyInfo);
                    currentStep = currentStep.Expression as MemberExpression;
                }
            }

            // Проходим по стеку и достраиваем дерево.
            BuildTreeNode <TBuildTreeNodeConfig> node = rootNode;
            PropertyInfo pathPart = null;

            while (propertiesPath.Count != 0)
            {
                pathPart = propertiesPath.Pop();

                if (!pathPart.PropertyType.IsSimple())
                {
                    if (!node.ChildNodes.ContainsKey(pathPart.Name))
                    {
                        node.ChildNodes[pathPart.Name] = new BuildTreeNode <TBuildTreeNodeConfig>(pathPart);
                    }

                    if (!isNeedParentNode || propertiesPath.Count != 0 && isNeedParentNode)
                    {
                        node = node.ChildNodes[pathPart.Name];
                    }
                }
            }

            callback(node, pathPart);
        }
Beispiel #3
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();
        }
Beispiel #4
0
 public AutoDifferenceSearchBuilder()
 {
     PropertyTree   = null;
     _buildRootNode = new BuildTreeNode <AutoBuildTreeNodeConfig>(typeof(TSource));
 }