/// <summary> /// Combines two <see cref="AlternatesCollection"/>. /// </summary> /// <remarks> /// First and second can be null. /// </remarks> /// <param name="first">First collection.</param> /// <param name="second">Second collection.</param> /// <returns>Combined <see cref="AlternatesCollection"/>.</returns> public static AlternatesCollection Combine(this AlternatesCollection first, AlternatesCollection second) { if (first == null) { return(second); } else if (second != null) { first.AddRange(second); } return(first); }
private async Task <ShapeBinding> GetShapeBindingAsync(string shapeType, AlternatesCollection shapeAlternates, ShapeTable shapeTable) { // shape alternates are optional, fully qualified binding names // the earliest added alternates have the lowest priority // the descriptor returned is based on the binding that is matched, so it may be an entirely // different descriptor if the alternate has a different base name for (var i = shapeAlternates.Count - 1; i >= 0; i--) { var shapeAlternate = shapeAlternates[i]; foreach (var shapeBindingResolver in _shapeBindingResolvers) { var binding = await shapeBindingResolver.GetShapeBindingAsync(shapeAlternate); if (binding != null) { return(binding); } } if (shapeTable.Bindings.TryGetValue(shapeAlternate, out var shapeBinding)) { return(shapeBinding); } } // when no alternates match, the shapeType is used to find the longest matching binding // the shapetype name can break itself into shorter fallbacks at double-underscore marks // so the shapetype itself may contain a longer alternate forms that falls back to a shorter one var shapeTypeScan = shapeType; do { foreach (var shapeBindingResolver in _shapeBindingResolvers) { var binding = await shapeBindingResolver.GetShapeBindingAsync(shapeTypeScan); if (binding != null) { return(binding); } } if (shapeTable.Bindings.TryGetValue(shapeTypeScan, out var shapeBinding)) { return(shapeBinding); } }while (TryGetParentShapeTypeName(ref shapeTypeScan)); return(null); }