[Perf] Replace Activator.CreateInstance with cached delegate in Model Binders
Fixes Part1 of #4470
This commit is contained in:
parent
fa29396141
commit
0e4b838864
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
|
|
@ -20,6 +21,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
/// <typeparam name="TElement">Type of elements in the collection.</typeparam>
|
/// <typeparam name="TElement">Type of elements in the collection.</typeparam>
|
||||||
public class CollectionModelBinder<TElement> : ICollectionModelBinder
|
public class CollectionModelBinder<TElement> : ICollectionModelBinder
|
||||||
{
|
{
|
||||||
|
private Func<object> _modelCreator;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="CollectionModelBinder{TElement}"/>.
|
/// Creates a new <see cref="CollectionModelBinder{TElement}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -147,7 +150,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
/// <returns>An instance of <paramref name="targetType"/>.</returns>
|
/// <returns>An instance of <paramref name="targetType"/>.</returns>
|
||||||
protected object CreateInstance(Type targetType)
|
protected object CreateInstance(Type targetType)
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(targetType);
|
if (_modelCreator == null)
|
||||||
|
{
|
||||||
|
_modelCreator = Expression
|
||||||
|
.Lambda<Func<object>>(Expression.New(targetType))
|
||||||
|
.Compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _modelCreator();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used when the ValueProvider contains the collection to be bound as a single element, e.g. the raw value
|
// Used when the ValueProvider contains the collection to be bound as a single element, e.g. the raw value
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
|
|
@ -15,6 +16,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
public class ComplexTypeModelBinder : IModelBinder
|
public class ComplexTypeModelBinder : IModelBinder
|
||||||
{
|
{
|
||||||
private readonly IDictionary<ModelMetadata, IModelBinder> _propertyBinders;
|
private readonly IDictionary<ModelMetadata, IModelBinder> _propertyBinders;
|
||||||
|
private Func<object> _modelCreator;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="ComplexTypeModelBinder"/>.
|
/// Creates a new <see cref="ComplexTypeModelBinder"/>.
|
||||||
|
|
@ -316,9 +318,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
||||||
throw new ArgumentNullException(nameof(bindingContext));
|
throw new ArgumentNullException(nameof(bindingContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the Activator throws an exception, we want to propagate it back up the call stack, since the
|
// If model creator throws an exception, we want to propagate it back up the call stack, since the
|
||||||
// application developer should know that this was an invalid type to try to bind to.
|
// application developer should know that this was an invalid type to try to bind to.
|
||||||
return Activator.CreateInstance(bindingContext.ModelType);
|
if (_modelCreator == null)
|
||||||
|
{
|
||||||
|
_modelCreator = Expression
|
||||||
|
.Lambda<Func<object>>(Expression.New(bindingContext.ModelType))
|
||||||
|
.Compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _modelCreator();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue