/// <summary> /// Generates a list of <see cref="FieldSelectorPart"/> for each <see cref="PropertyInfo"/> in the supplied list. /// </summary> /// <param name="propertyInfos">The <see cref="PropertyInfo"/> instances.</param> /// <param name="currentDeep">The current deep of the recursion.</param> /// <param name="maximumDeep">The maximum recursion deep to prevent a <see cref="StackOverflowException" /> on endless nested types.</param> /// <returns>The list of <see cref="FieldSelectorPart"/>.</returns> /// <exception cref="ArgumentNullException">The value of '<paramref name="propertyInfos"/>' cannot be null. </exception> private IEnumerable <FieldSelectorPart> GenerateChildTreeFromProperties([NotNull] IEnumerable <PropertyInfo> propertyInfos, Int32 currentDeep, Int32 maximumDeep) { if (propertyInfos == null) { throw new ArgumentNullException(nameof(propertyInfos)); } if (currentDeep == maximumDeep) { yield break; } foreach (var propertyInfo in propertyInfos) { var partName = this.partNameExtractor.ExtractPartName(propertyInfo); var childPart = new FieldSelectorPart(partName); var nextType = propertyInfo.PropertyType; if (!nextType.IsPrimitive()) { if (propertyInfo.PropertyType.IsIEnumerable() && !propertyInfo.PropertyType.IsPrimitive()) { nextType = propertyInfo.PropertyType.GetSingleGenericParameter(); } foreach (var childPartOfChildPart in this.GenerateChildTreeFromProperties(nextType.GetProperties(), currentDeep + 1, maximumDeep)) { childPart.AddPart(childPartOfChildPart); } } yield return(childPart); } }
public FieldSelectorTree GenerateFromLambdaExpression <TProperty>([NotNull] Expression <Func <TRoot, TProperty> > selector) { if (selector == null) { throw new ArgumentNullException(nameof(selector)); } this.rootPart = new FieldSelectorTree(); this.Visit(selector); FieldSelectorPart addCurrentToMe = null; foreach (var childPart in this.fieldSelectorParts) { if (!this.rootPart.ChildParts.Any()) { addCurrentToMe = childPart; this.rootPart.AddPart(childPart); } else if (addCurrentToMe != null) { addCurrentToMe.AddPart(childPart); addCurrentToMe = childPart; } } var result = this.rootPart; this.rootPart = null; return(result); }
private IEnumerable <FieldSelectorPart> MergeChildPart([NotNull] IEnumerable <IGrouping <String, FieldSelectorPart> > groupedPart) { if (groupedPart == null) { throw new ArgumentNullException(nameof(groupedPart)); } foreach (var group in groupedPart) { var mergedChildPart = new FieldSelectorPart(group.Key); foreach (var childPart in this.MergeChildPart(group.SelectMany(m => m.ChildParts).GroupBy(m => m.PartName))) { mergedChildPart.AddPart(childPart); } yield return(mergedChildPart); } }
private FieldSelectorTree MergeRootParts([NotNull] IEnumerable <FieldSelectorTree> rootParts) { if (rootParts == null) { throw new ArgumentNullException(nameof(rootParts)); } var result = new FieldSelectorTree(); foreach (var firstLevel in rootParts.SelectMany(m => m.ChildParts).GroupBy(m => m.PartName)) { var childgroup = new FieldSelectorPart(firstLevel.Key); foreach (var part in this.MergeChildPart(firstLevel.SelectMany(m => m.ChildParts).GroupBy(m => m.PartName))) { childgroup.AddPart(part); } result.AddPart(childgroup); } return(result); }