From 0e4b838864d188046fb73497accd1b2416da96d0 Mon Sep 17 00:00:00 2001 From: mnltejaswini Date: Wed, 27 Apr 2016 15:19:03 -0700 Subject: [PATCH] [Perf] Replace Activator.CreateInstance with cached delegate in Model Binders Fixes Part1 of #4470 --- .../ModelBinding/Binders/CollectionModelBinder.cs | 13 ++++++++++++- .../ModelBinding/Binders/ComplexTypeModelBinder.cs | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/CollectionModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/CollectionModelBinder.cs index 47d3405726..6c368f4533 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/CollectionModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/CollectionModelBinder.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; +using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Internal; @@ -20,6 +21,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders /// Type of elements in the collection. public class CollectionModelBinder : ICollectionModelBinder { + private Func _modelCreator; + /// /// Creates a new . /// @@ -147,7 +150,15 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders /// An instance of . protected object CreateInstance(Type targetType) { - return Activator.CreateInstance(targetType); + if (_modelCreator == null) + { + _modelCreator = Expression + .Lambda>(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 diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/ComplexTypeModelBinder.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/ComplexTypeModelBinder.cs index 71a3154822..1b55ddbf7c 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/ComplexTypeModelBinder.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/ComplexTypeModelBinder.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Internal; @@ -15,6 +16,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders public class ComplexTypeModelBinder : IModelBinder { private readonly IDictionary _propertyBinders; + private Func _modelCreator; /// /// Creates a new . @@ -316,9 +318,17 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders 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. - return Activator.CreateInstance(bindingContext.ModelType); + if (_modelCreator == null) + { + _modelCreator = Expression + .Lambda>(Expression.New(bindingContext.ModelType)) + .Compile(); + } + + return _modelCreator(); + } ///