// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding { /// /// Represents a whose values come from a collection of s. /// public class CompositeValueProvider : Collection, IEnumerableValueProvider, IBindingSourceValueProvider { /// /// Initializes a new instance of . /// public CompositeValueProvider() : base() { } /// /// Initializes a new instance of . /// /// The sequence of to add to this instance of /// . public CompositeValueProvider(IEnumerable valueProviders) : base(valueProviders.ToList()) { } /// /// Creates a new from the provided /// and . /// /// The set of instances. /// The . /// /// A containing all instances /// created. /// public static CompositeValueProvider Create( [NotNull] IEnumerable factories, [NotNull] ValueProviderFactoryContext context) { var composite = new CompositeValueProvider(); foreach (var valueProvidersFactory in factories) { var valueProvider = valueProvidersFactory.GetValueProvider(context); if (valueProvider != null) { composite.Add(valueProvider); } } return composite; } /// public virtual async Task ContainsPrefixAsync(string prefix) { for (var i = 0; i < Count; i++) { if (await this[i].ContainsPrefixAsync(prefix)) { return true; } } return false; } /// public virtual async Task GetValueAsync(string key) { // Performance-sensitive // Caching the count is faster for IList var itemCount = Items.Count; for (var i = 0; i < itemCount; i++) { var valueProvider = Items[i]; var result = await valueProvider.GetValueAsync(key); if (result != null) { return result; } } return null; } /// public virtual async Task> GetKeysFromPrefixAsync(string prefix) { foreach (var valueProvider in this) { var enumeratedProvider = valueProvider as IEnumerableValueProvider; if (enumeratedProvider != null) { var result = await enumeratedProvider.GetKeysFromPrefixAsync(prefix); if (result != null && result.Count > 0) { return result; } } } return new Dictionary(StringComparer.OrdinalIgnoreCase); } /// protected override void InsertItem(int index, [NotNull] IValueProvider item) { base.InsertItem(index, item); } /// protected override void SetItem(int index, [NotNull] IValueProvider item) { base.SetItem(index, item); } /// public IValueProvider Filter(BindingSource bindingSource) { var filteredValueProviders = new List(); foreach (var valueProvider in this.OfType()) { var result = valueProvider.Filter(bindingSource); if (result != null) { filteredValueProviders.Add(result); } } if (filteredValueProviders.Count == 0) { // Do not create an empty CompositeValueProvider. return null; } if (filteredValueProviders.Count == Count) { // No need for a new CompositeValueProvider. return this; } return new CompositeValueProvider(filteredValueProviders); } } }