Munch on less memory when handling property metadata
- #5499 - switch `foreach` to `for` and use less Linq when accessing `modelMetadata.Properties` - change backing field for `ModelExplorer.Properties` from a list to an array
This commit is contained in:
parent
48546dbb28
commit
7178464ed2
|
|
@ -623,7 +623,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
|
|||
//
|
||||
if (modelMetadata.IsEnumerableType ||
|
||||
!modelMetadata.IsComplexType ||
|
||||
!modelMetadata.Properties.Any())
|
||||
modelMetadata.Properties.Count == 0)
|
||||
{
|
||||
Context.Results.Add(CreateResult(bindingContext, source ?? ambientSource, containerName));
|
||||
return;
|
||||
|
|
@ -656,10 +656,10 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
|
|||
newContainerName = GetName(containerName, bindingContext);
|
||||
}
|
||||
|
||||
foreach (var propertyMetadata in modelMetadata.Properties)
|
||||
for (var i = 0; i < modelMetadata.Properties.Count; i++)
|
||||
{
|
||||
var propertyMetadata = modelMetadata.Properties[i];
|
||||
var key = new PropertyKey(propertyMetadata, source);
|
||||
|
||||
var propertyContext = ApiParameterDescriptionContext.GetContext(
|
||||
propertyMetadata,
|
||||
bindingInfo: null,
|
||||
|
|
|
|||
|
|
@ -60,8 +60,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
bindingContext.Model = CreateModel(bindingContext);
|
||||
}
|
||||
|
||||
foreach (var property in bindingContext.ModelMetadata.Properties)
|
||||
for (var i = 0; i < bindingContext.ModelMetadata.Properties.Count; i++)
|
||||
{
|
||||
var property = bindingContext.ModelMetadata.Properties[i];
|
||||
if (!CanBindProperty(bindingContext, property))
|
||||
{
|
||||
continue;
|
||||
|
|
@ -228,8 +229,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
//
|
||||
var hasBindableProperty = false;
|
||||
var isAnyPropertyEnabledForValueProviderBasedBinding = false;
|
||||
foreach (var propertyMetadata in bindingContext.ModelMetadata.Properties)
|
||||
for (var i = 0; i < bindingContext.ModelMetadata.Properties.Count; i++)
|
||||
{
|
||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[i];
|
||||
if (!CanBindProperty(bindingContext, propertyMetadata))
|
||||
{
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||
{
|
||||
|
|
@ -25,8 +25,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
HasDefaultConstructor(context.Metadata.ModelType.GetTypeInfo()))
|
||||
{
|
||||
var propertyBinders = new Dictionary<ModelMetadata, IModelBinder>();
|
||||
foreach (var property in context.Metadata.Properties)
|
||||
for (var i = 0; i < context.Metadata.Properties.Count; i++)
|
||||
{
|
||||
var property = context.Metadata.Properties[i];
|
||||
propertyBinders.Add(property, context.CreateBinder(property));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -463,8 +463,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Internal
|
|||
}
|
||||
else if (modelMetadata.IsComplexType)
|
||||
{
|
||||
foreach (var property in modelMetadata.Properties)
|
||||
for (var i = 0; i < modelMetadata.Properties.Count; i++)
|
||||
{
|
||||
var property = modelMetadata.Properties[i];
|
||||
modelState.ClearValidationState(property.BinderModelName ?? property.PropertyName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,9 +129,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
if (string.IsNullOrEmpty(modelKey))
|
||||
{
|
||||
var modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(TModel));
|
||||
|
||||
foreach (var property in modelMetadata.Properties)
|
||||
for (var i = 0; i < modelMetadata.Properties.Count; i++)
|
||||
{
|
||||
var property = modelMetadata.Properties[i];
|
||||
var childKey = property.BinderModelName ?? property.PropertyName;
|
||||
var entries = modelState.FindKeysWithPrefix(childKey).ToArray();
|
||||
foreach (var entry in entries)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
|
|
@ -20,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
|||
|
||||
private object _model;
|
||||
private Func<object, object> _modelAccessor;
|
||||
private List<ModelExplorer> _properties;
|
||||
private ModelExplorer[] _properties;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ModelExplorer"/>.
|
||||
|
|
@ -198,24 +197,38 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
|||
/// Includes a <see cref="ModelExplorer"/> for each property of the <see cref="ModelMetadata"/>
|
||||
/// for <see cref="ModelType"/>.
|
||||
/// </remarks>
|
||||
public IEnumerable<ModelExplorer> Properties
|
||||
public IEnumerable<ModelExplorer> Properties => PropertiesInternal;
|
||||
|
||||
private ModelExplorer[] PropertiesInternal
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_properties == null)
|
||||
{
|
||||
_properties = new List<ModelExplorer>();
|
||||
|
||||
var metadata = GetMetadataForRuntimeType();
|
||||
var properties = metadata.Properties;
|
||||
var propertyHelpers = PropertyHelper.GetProperties(ModelType);
|
||||
|
||||
var properties = Enumerable.Join(
|
||||
metadata.Properties,
|
||||
PropertyHelper.GetProperties(ModelType),
|
||||
m => m.PropertyName,
|
||||
ph => ph.Property.Name,
|
||||
(m, ph) => CreateExplorerForProperty(m, ph));
|
||||
_properties = new ModelExplorer[properties.Count];
|
||||
for (var i = 0; i < properties.Count; i++)
|
||||
{
|
||||
var propertyMetadata = properties[i];
|
||||
PropertyHelper propertyHelper = null;
|
||||
for (var j = 0; j < propertyHelpers.Length; j++)
|
||||
{
|
||||
if (string.Equals(
|
||||
propertyMetadata.PropertyName,
|
||||
propertyHelpers[j].Property.Name,
|
||||
StringComparison.Ordinal))
|
||||
{
|
||||
propertyHelper = propertyHelpers[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_properties.AddRange(properties);
|
||||
Debug.Assert(propertyHelper != null);
|
||||
_properties[i] = CreateExplorerForProperty(propertyMetadata, propertyHelper);
|
||||
}
|
||||
}
|
||||
|
||||
return _properties;
|
||||
|
|
@ -252,10 +265,16 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
|||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
return Properties.FirstOrDefault(p => string.Equals(
|
||||
p.Metadata.PropertyName,
|
||||
name,
|
||||
StringComparison.Ordinal));
|
||||
for (var i = 0; i < PropertiesInternal.Length; i++)
|
||||
{
|
||||
var property = PropertiesInternal[i];
|
||||
if (string.Equals(name, property.Metadata.PropertyName, StringComparison.Ordinal))
|
||||
{
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue