// 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);
}
}
}