Reducing allocations in value providers
- Don't go async in formdata providers unless we need to - Remove unnecessary defensive copy in CompositeValueProvider
This commit is contained in:
parent
082f175b48
commit
0dadf56fc8
|
|
@ -0,0 +1,18 @@
|
|||
// 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.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Internal
|
||||
{
|
||||
public static class TaskCache<T>
|
||||
{
|
||||
private static readonly Task<T> _defaultCompletedTask = Task.FromResult(default(T));
|
||||
|
||||
/// <summary>
|
||||
/// Gets a completed <see cref="Task"/> with the value of <c>default(T)</c>.
|
||||
/// </summary>
|
||||
public static Task<T> DefaultCompletedTask => _defaultCompletedTask;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -30,8 +30,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// </summary>
|
||||
/// <param name="valueProviders">The sequence of <see cref="IValueProvider"/> to add to this instance of
|
||||
/// <see cref="CompositeValueProvider"/>.</param>
|
||||
public CompositeValueProvider(IEnumerable<IValueProvider> valueProviders)
|
||||
: base(valueProviders.ToList())
|
||||
protected CompositeValueProvider(IList<IValueProvider> valueProviders)
|
||||
: base(valueProviders)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ using System;
|
|||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class FormValueProviderFactory : IValueProviderFactory
|
||||
{
|
||||
public async Task<IValueProvider> GetValueProviderAsync(ValueProviderFactoryContext context)
|
||||
public Task<IValueProvider> GetValueProviderAsync(ValueProviderFactoryContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
|
|
@ -18,23 +19,20 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
|
||||
var request = context.HttpContext.Request;
|
||||
|
||||
if (request.HasFormContentType)
|
||||
{
|
||||
var culture = GetCultureInfo(request);
|
||||
|
||||
return new ReadableStringCollectionValueProvider(
|
||||
BindingSource.Form,
|
||||
await request.ReadFormAsync(),
|
||||
culture);
|
||||
return CreateValueProviderAsync(request);
|
||||
}
|
||||
|
||||
return null;
|
||||
return TaskCache<IValueProvider>.DefaultCompletedTask;
|
||||
}
|
||||
|
||||
private static CultureInfo GetCultureInfo(HttpRequest request)
|
||||
private static async Task<IValueProvider> CreateValueProviderAsync(HttpRequest request)
|
||||
{
|
||||
return CultureInfo.CurrentCulture;
|
||||
return new ReadableStringCollectionValueProvider(
|
||||
BindingSource.Form,
|
||||
await request.ReadFormAsync(),
|
||||
CultureInfo.CurrentCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,30 +8,35 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class JQueryFormValueProviderFactory : IValueProviderFactory
|
||||
{
|
||||
public async Task<IValueProvider> GetValueProviderAsync(ValueProviderFactoryContext context)
|
||||
public Task<IValueProvider> GetValueProviderAsync(ValueProviderFactoryContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
|
||||
var request = context.HttpContext.Request;
|
||||
|
||||
if (request.HasFormContentType)
|
||||
{
|
||||
return new JQueryFormValueProvider(
|
||||
return CreateValueProviderAsync(request);
|
||||
}
|
||||
|
||||
return TaskCache<IValueProvider>.DefaultCompletedTask;
|
||||
}
|
||||
|
||||
private static async Task<IValueProvider> CreateValueProviderAsync(HttpRequest request)
|
||||
{
|
||||
return new JQueryFormValueProvider(
|
||||
BindingSource.Form,
|
||||
await GetValueCollectionAsync(request),
|
||||
CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static async Task<IDictionary<string, StringValues>> GetValueCollectionAsync(HttpRequest request)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
new JQueryFormValueProvider(bindingSource, new Dictionary<string, StringValues>(), culture);
|
||||
var valueProvider = new JQueryFormValueProvider(bindingSource, values, culture);
|
||||
|
||||
return new CompositeValueProvider(new[] { emptyValueProvider, valueProvider });
|
||||
return new CompositeValueProvider() { emptyValueProvider, valueProvider };
|
||||
}
|
||||
|
||||
#if DNX451
|
||||
|
|
@ -43,7 +43,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
provider2.Setup(p => p.GetKeysFromPrefix("prefix"))
|
||||
.Returns(dictionary)
|
||||
.Verifiable();
|
||||
var provider = new CompositeValueProvider(new[] { provider1, provider2.Object });
|
||||
var provider = new CompositeValueProvider() { provider1, provider2.Object };
|
||||
|
||||
// Act
|
||||
var values = provider.GetKeysFromPrefix("prefix");
|
||||
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
// Arrange
|
||||
var provider1 = Mock.Of<IValueProvider>();
|
||||
var provider2 = Mock.Of<IValueProvider>();
|
||||
var provider = new CompositeValueProvider(new[] { provider1, provider2 });
|
||||
var provider = new CompositeValueProvider() { provider1, provider2 };
|
||||
|
||||
// Act
|
||||
var values = provider.GetKeysFromPrefix("prefix");
|
||||
|
|
@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var valueProvider1 = GetMockValueProvider("Test");
|
||||
var valueProvider2 = GetMockValueProvider("Unrelated");
|
||||
|
||||
var provider = new CompositeValueProvider(new List<IValueProvider>() { valueProvider1.Object, valueProvider2.Object });
|
||||
var provider = new CompositeValueProvider() { valueProvider1.Object, valueProvider2.Object };
|
||||
|
||||
// Act
|
||||
var result = provider.Filter(metadata.BindingSource);
|
||||
|
|
|
|||
Loading…
Reference in New Issue