2using System.Collections.Generic;
23 private readonly
int[] _rootItemIds;
24 private readonly
int[] _leafItemIds;
25 private readonly
int[] _isolatedItemIds;
26 private readonly
int[] _sharedComponentItemIds;
27 private readonly
int[] _cyclicItemIds;
28 private readonly
string[] _errors;
29 private readonly
string[] _warnings;
85 int relationshipCount,
86 int connectedComponentCount,
88 int maximumImmediateComponentCount,
89 int maximumImmediateParentCount,
90 IEnumerable<int> rootItemIds,
91 IEnumerable<int> leafItemIds,
92 IEnumerable<int> isolatedItemIds,
93 IEnumerable<int> sharedComponentItemIds,
94 IEnumerable<int> cyclicItemIds,
95 IEnumerable<string> errors,
96 IEnumerable<string> warnings)
98 ValidateNonNegativeCount(
102 ValidateNonNegativeCount(
104 nameof(relationshipCount));
106 ValidateNonNegativeCount(
107 connectedComponentCount,
108 nameof(connectedComponentCount));
110 ValidateNonNegativeCount(
112 nameof(maximumDepth));
114 ValidateNonNegativeCount(
115 maximumImmediateComponentCount,
116 nameof(maximumImmediateComponentCount));
118 ValidateNonNegativeCount(
119 maximumImmediateParentCount,
120 nameof(maximumImmediateParentCount));
127 connectedComponentCount;
132 maximumImmediateComponentCount;
135 maximumImmediateParentCount;
140 nameof(rootItemIds));
145 nameof(leafItemIds));
150 nameof(isolatedItemIds));
152 _sharedComponentItemIds =
154 sharedComponentItemIds,
155 nameof(sharedComponentItemIds));
160 nameof(cyclicItemIds));
172 if (_cyclicItemIds.Length > 0 &&
175 throw new ArgumentException(
176 "A cyclic product structure cannot have " +
177 "a valid detected structure type.",
178 nameof(detectedType));
264 _sharedComponentItemIds;
298 IsolatedItemIds.Count > 0;
305 SharedComponentItemIds.Count > 0;
312 CyclicItemIds.Count > 0;
370 $
"{DetectedType} — {validity}; " +
371 $
"{ItemCount} items; " +
372 $
"{RelationshipCount} relationships; " +
373 $
"depth {MaximumDepth}";
376 private static int[] NormalizeItemIds(
377 IEnumerable<int> itemIds,
378 string parameterName)
380 ArgumentNullException.ThrowIfNull(itemIds);
382 int[] normalizedItemIds =
390 if (normalizedItemIds.Any(
394 throw new ArgumentException(
395 "Every item identifier must be " +
396 "strictly positive.",
400 return normalizedItemIds;
403 private static string[] NormalizeMessages(
404 IEnumerable<string> messages,
405 string parameterName)
407 ArgumentNullException.ThrowIfNull(messages);
412 !
string.IsNullOrWhiteSpace(
418 StringComparer.Ordinal)
422 private static void ValidateNonNegativeCount(
424 string parameterName)
428 throw new ArgumentOutOfRangeException(
431 "The value cannot be negative.");
int MaximumImmediateParentCount
Gets the largest number of immediate parent items consuming a single component.
bool HasIsolatedItems
Gets a value indicating whether at least one item has no bill-of-materials relationship.
ProductStructureAnalysis(ProductStructureType detectedType, int itemCount, int relationshipCount, int connectedComponentCount, int maximumDepth, int maximumImmediateComponentCount, int maximumImmediateParentCount, IEnumerable< int > rootItemIds, IEnumerable< int > leafItemIds, IEnumerable< int > isolatedItemIds, IEnumerable< int > sharedComponentItemIds, IEnumerable< int > cyclicItemIds, IEnumerable< string > errors, IEnumerable< string > warnings)
Initializes a product-structure analysis result.
bool HasWarnings
Gets a value indicating whether at least one warning was detected.
int ItemCount
Gets the number of items considered by the analysis.
bool IsMultiLevel
Gets a value indicating whether the product structure contains more than one bill-of-materials level.
bool HasErrors
Gets a value indicating whether at least one error was detected.
IReadOnlyList< int > LeafItemIds
Gets the identifiers of leaf items.
int RelationshipCount
Gets the number of distinct component-to-parent relationships.
int MaximumImmediateComponentCount
Gets the largest number of immediate components consumed by a single parent item.
int ConnectedComponentCount
Gets the number of connected components in the underlying undirected product-structure graph.
bool HasCycle
Gets a value indicating whether the product-structure graph contains at least one directed cycle.
override string ToString()
int MaximumDepth
Gets the maximum number of relationships on a directed path from a leaf item to a root item.
bool HasRelationships
Gets a value indicating whether the product-structure graph contains at least one relationship.
IReadOnlyList< int > SharedComponentItemIds
Gets the identifiers of components consumed by more than one immediate parent item.
ProductStructureType DetectedType
Gets the product-structure type detected by the analyzer.
bool HasAssemblyNodes
Gets a value indicating whether at least one parent item consumes several immediate components.
IReadOnlyList< string > Errors
Gets the errors detected during the analysis.
bool HasDivergentComponents
Gets a value indicating whether at least one component is consumed by several immediate parent items.
IReadOnlyList< int > IsolatedItemIds
Gets the identifiers of items having no bill-of-materials relationship.
bool IsValid
Gets a value indicating whether the analyzed graph is structurally valid.
IReadOnlyList< int > CyclicItemIds
Gets the identifiers of items belonging to at least one directed cycle.
bool HasSharedComponents
Gets a value indicating whether at least one component is consumed by several immediate parent items.
IReadOnlyList< int > RootItemIds
Gets the identifiers of root items.
IReadOnlyList< string > Warnings
Gets the non-fatal warnings detected during the analysis.
ProductStructureType
Identifies the structural category of a product bill-of-materials graph.