From 787aed403f824b21c264336fd21ef46e291fcbc9 Mon Sep 17 00:00:00 2001 From: martincostello Date: Sat, 30 May 2020 21:13:45 +0100 Subject: [PATCH 1/2] Reuse model binders Reuse the same model binders for CancellationTokens and services, rather than allocating a new one for every request with such a parameter. --- .../Binders/CancellationTokenModelBinderProvider.cs | 4 +++- .../src/ModelBinding/Binders/ServicesModelBinderProvider.cs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs index b3ee6f736112..e5e300c87ea8 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs @@ -11,6 +11,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders /// public class CancellationTokenModelBinderProvider : IModelBinderProvider { + private CancellationTokenModelBinder _modelBinder; + /// public IModelBinder GetBinder(ModelBinderProviderContext context) { @@ -21,7 +23,7 @@ public IModelBinder GetBinder(ModelBinderProviderContext context) if (context.Metadata.ModelType == typeof(CancellationToken)) { - return new CancellationTokenModelBinder(); + return _modelBinder ??= new CancellationTokenModelBinder(); } return null; diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs index 2dea775a0a12..18c46192ec4c 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs @@ -10,6 +10,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders /// public class ServicesModelBinderProvider : IModelBinderProvider { + private ServicesModelBinder _modelBinder; + /// public IModelBinder GetBinder(ModelBinderProviderContext context) { @@ -21,7 +23,7 @@ public IModelBinder GetBinder(ModelBinderProviderContext context) if (context.BindingInfo.BindingSource != null && context.BindingInfo.BindingSource.CanAcceptDataFrom(BindingSource.Services)) { - return new ServicesModelBinder(); + return _modelBinder ??= new ServicesModelBinder(); } return null; From 00108c94576866846e35b4dfda0a35be185784bb Mon Sep 17 00:00:00 2001 From: martincostello Date: Wed, 3 Jun 2020 14:57:23 +0100 Subject: [PATCH 2/2] Make fields readonly Make the fields backing the binder once when initialized, rather than on first use. Co-Authored-By: Pranav K --- .../Binders/CancellationTokenModelBinderProvider.cs | 6 ++++-- .../src/ModelBinding/Binders/ServicesModelBinderProvider.cs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs index e5e300c87ea8..6819805276de 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/CancellationTokenModelBinderProvider.cs @@ -11,7 +11,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders /// public class CancellationTokenModelBinderProvider : IModelBinderProvider { - private CancellationTokenModelBinder _modelBinder; + // CancellationTokenModelBinder does not have any state. Re-use the same instance for binding. + + private readonly CancellationTokenModelBinder _modelBinder = new CancellationTokenModelBinder(); /// public IModelBinder GetBinder(ModelBinderProviderContext context) @@ -23,7 +25,7 @@ public IModelBinder GetBinder(ModelBinderProviderContext context) if (context.Metadata.ModelType == typeof(CancellationToken)) { - return _modelBinder ??= new CancellationTokenModelBinder(); + return _modelBinder; } return null; diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs index 18c46192ec4c..b09d625c4dca 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ServicesModelBinderProvider.cs @@ -10,7 +10,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders /// public class ServicesModelBinderProvider : IModelBinderProvider { - private ServicesModelBinder _modelBinder; + // ServicesModelBinder does not have any state. Re-use the same instance for binding. + + private readonly ServicesModelBinder _modelBinder = new ServicesModelBinder(); /// public IModelBinder GetBinder(ModelBinderProviderContext context) @@ -23,7 +25,7 @@ public IModelBinder GetBinder(ModelBinderProviderContext context) if (context.BindingInfo.BindingSource != null && context.BindingInfo.BindingSource.CanAcceptDataFrom(BindingSource.Services)) { - return _modelBinder ??= new ServicesModelBinder(); + return _modelBinder; } return null;