Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Fowler <davidfowl@gmail.com>2020-11-12 07:57:53 +0300
committerDavid Fowler <davidfowl@gmail.com>2020-11-12 07:57:53 +0300
commite9d16525cf3a832631a4e29ce826290adae873a9 (patch)
tree390d5e2bc9dc9728ae51ffad232fc5c9e686f1bb
parent15a8515724cf21046dfd40685fdc10240a628362 (diff)
-rw-r--r--src/Mvc/Mvc.Core/src/Controllers/ControllerBinderDelegateProvider.cs34
-rw-r--r--src/Mvc/Mvc.Core/src/Controllers/ControllerFactoryProvider.cs24
-rw-r--r--src/Mvc/Mvc.Core/src/Controllers/DefaultControllerPropertyActivator.cs6
-rw-r--r--src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvokerCache.cs62
-rw-r--r--src/Mvc/Mvc.Core/src/Routing/ControllerRequestDelegateFactory.cs5
5 files changed, 82 insertions, 49 deletions
diff --git a/src/Mvc/Mvc.Core/src/Controllers/ControllerBinderDelegateProvider.cs b/src/Mvc/Mvc.Core/src/Controllers/ControllerBinderDelegateProvider.cs
index a590b6b19d..33a7c8e12f 100644
--- a/src/Mvc/Mvc.Core/src/Controllers/ControllerBinderDelegateProvider.cs
+++ b/src/Mvc/Mvc.Core/src/Controllers/ControllerBinderDelegateProvider.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -46,8 +46,8 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
var parameterBindingInfo = GetParameterBindingInfo(
modelBinderFactory,
modelMetadataProvider,
- actionDescriptor,
- mvcOptions);
+ actionDescriptor);
+
var propertyBindingInfo = GetPropertyBindingInfo(modelBinderFactory, modelMetadataProvider, actionDescriptor);
if (parameterBindingInfo == null && propertyBindingInfo == null)
@@ -55,9 +55,21 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
return null;
}
- return Bind;
+ if (propertyBindingInfo == null)
+ {
+ return async (controllerContext, controller, arguments) =>
+ {
+ var (success, valueProvider) = await CompositeValueProvider.TryCreateAsync(controllerContext, controllerContext.ValueProviderFactories);
+ if (!success)
+ {
+ return;
+ }
+
+ await BindArguments(valueProvider, controllerContext, arguments);
+ };
+ }
- async Task Bind(ControllerContext controllerContext, object controller, Dictionary<string, object> arguments)
+ return async (controllerContext, controller, arguments) =>
{
var (success, valueProvider) = await CompositeValueProvider.TryCreateAsync(controllerContext, controllerContext.ValueProviderFactories);
if (!success)
@@ -65,6 +77,12 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
return;
}
+ await BindArguments(valueProvider, controllerContext, arguments);
+ await BindProperties(valueProvider, controllerContext, controller, arguments);
+ };
+
+ async Task BindArguments(IValueProvider valueProvider, ControllerContext controllerContext, Dictionary<string, object> arguments)
+ {
var parameters = actionDescriptor.Parameters;
for (var i = 0; i < parameters.Count; i++)
@@ -92,7 +110,10 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
arguments[parameter.Name] = result.Model;
}
}
+ }
+ async Task BindProperties(IValueProvider valueProvider, ControllerContext controllerContext, object controller, Dictionary<string, object> arguments)
+ {
var properties = actionDescriptor.BoundProperties;
for (var i = 0; i < properties.Count; i++)
{
@@ -125,8 +146,7 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
private static BinderItem[] GetParameterBindingInfo(
IModelBinderFactory modelBinderFactory,
IModelMetadataProvider modelMetadataProvider,
- ControllerActionDescriptor actionDescriptor,
- MvcOptions mvcOptions)
+ ControllerActionDescriptor actionDescriptor)
{
var parameters = actionDescriptor.Parameters;
if (parameters.Count == 0)
diff --git a/src/Mvc/Mvc.Core/src/Controllers/ControllerFactoryProvider.cs b/src/Mvc/Mvc.Core/src/Controllers/ControllerFactoryProvider.cs
index 5c0ee05088..a75c9b9951 100644
--- a/src/Mvc/Mvc.Core/src/Controllers/ControllerFactoryProvider.cs
+++ b/src/Mvc/Mvc.Core/src/Controllers/ControllerFactoryProvider.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -65,6 +65,12 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
var controllerActivator = _activatorProvider.CreateActivator(descriptor);
var propertyActivators = GetPropertiesToActivate(descriptor);
+
+ if (propertyActivators == null)
+ {
+ return controllerActivator;
+ }
+
object CreateController(ControllerContext controllerContext)
{
var controller = controllerActivator(controllerContext);
@@ -106,14 +112,24 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
private Action<ControllerContext, object>[] GetPropertiesToActivate(ControllerActionDescriptor actionDescriptor)
{
- var propertyActivators = new Action<ControllerContext, object>[_propertyActivators.Length];
+ List<Action<ControllerContext, object>> propertyActivators = null;
+
for (var i = 0; i < _propertyActivators.Length; i++)
{
var activatorProvider = _propertyActivators[i];
- propertyActivators[i] = activatorProvider.GetActivatorDelegate(actionDescriptor);
+ var activator = activatorProvider.GetActivatorDelegate(actionDescriptor);
+ if (activator != null)
+ {
+ if (propertyActivators == null)
+ {
+ propertyActivators = new List<Action<ControllerContext, object>>(_propertyActivators.Length);
+ }
+
+ propertyActivators.Add(activator);
+ }
}
- return propertyActivators;
+ return propertyActivators?.ToArray();
}
}
}
diff --git a/src/Mvc/Mvc.Core/src/Controllers/DefaultControllerPropertyActivator.cs b/src/Mvc/Mvc.Core/src/Controllers/DefaultControllerPropertyActivator.cs
index 20f0b74ecc..5d848e3553 100644
--- a/src/Mvc/Mvc.Core/src/Controllers/DefaultControllerPropertyActivator.cs
+++ b/src/Mvc/Mvc.Core/src/Controllers/DefaultControllerPropertyActivator.cs
@@ -55,6 +55,12 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
}
var propertiesToActivate = GetPropertiesToActivate(controllerType);
+
+ if (propertiesToActivate.Length == 0)
+ {
+ return null;
+ }
+
void Activate(ControllerContext controllerContext, object controller)
{
for (var i = 0; i < propertiesToActivate.Length; i++)
diff --git a/src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvokerCache.cs b/src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvokerCache.cs
index 6be4771bb7..80472e9fbb 100644
--- a/src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvokerCache.cs
+++ b/src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvokerCache.cs
@@ -61,42 +61,34 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
}
}
- public ControllerActionInvokerCacheEntry GetCachedEntry(ControllerActionDescriptor actionDescriptor)
+ public ControllerActionInvokerCacheEntry CreateEntry(ControllerActionDescriptor actionDescriptor)
{
- var cache = CurrentCache;
-
- if (!cache.Entries.TryGetValue(actionDescriptor, out var cacheEntry))
- {
- var parameterDefaultValues = ParameterDefaultValues
- .GetParameterDefaultValues(actionDescriptor.MethodInfo);
-
- var objectMethodExecutor = ObjectMethodExecutor.Create(
- actionDescriptor.MethodInfo,
- actionDescriptor.ControllerTypeInfo,
- parameterDefaultValues);
-
- var controllerFactory = _controllerFactoryProvider.CreateControllerFactory(actionDescriptor);
- var controllerReleaser = _controllerFactoryProvider.CreateControllerReleaser(actionDescriptor);
- var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate(
- _parameterBinder,
- _modelBinderFactory,
- _modelMetadataProvider,
- actionDescriptor,
- _mvcOptions);
-
- var actionMethodExecutor = ActionMethodExecutor.GetExecutor(objectMethodExecutor);
-
- cacheEntry = new ControllerActionInvokerCacheEntry(
- Array.Empty<FilterItem>(),
- controllerFactory,
- controllerReleaser,
- propertyBinderFactory,
- objectMethodExecutor,
- actionMethodExecutor);
- cacheEntry = cache.Entries.GetOrAdd(actionDescriptor, cacheEntry);
- }
-
- return cacheEntry;
+ var parameterDefaultValues = ParameterDefaultValues
+ .GetParameterDefaultValues(actionDescriptor.MethodInfo);
+
+ var objectMethodExecutor = ObjectMethodExecutor.Create(
+ actionDescriptor.MethodInfo,
+ actionDescriptor.ControllerTypeInfo,
+ parameterDefaultValues);
+
+ var controllerFactory = _controllerFactoryProvider.CreateControllerFactory(actionDescriptor);
+ var controllerReleaser = _controllerFactoryProvider.CreateControllerReleaser(actionDescriptor);
+ var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate(
+ _parameterBinder,
+ _modelBinderFactory,
+ _modelMetadataProvider,
+ actionDescriptor,
+ _mvcOptions);
+
+ var actionMethodExecutor = ActionMethodExecutor.GetExecutor(objectMethodExecutor);
+
+ return new ControllerActionInvokerCacheEntry(
+ Array.Empty<FilterItem>(),
+ controllerFactory,
+ controllerReleaser,
+ propertyBinderFactory,
+ objectMethodExecutor,
+ actionMethodExecutor);
}
public (ControllerActionInvokerCacheEntry cacheEntry, IFilterMetadata[] filters) GetCachedResult(ControllerContext controllerContext)
diff --git a/src/Mvc/Mvc.Core/src/Routing/ControllerRequestDelegateFactory.cs b/src/Mvc/Mvc.Core/src/Routing/ControllerRequestDelegateFactory.cs
index 03bcd94deb..3d4cbf398d 100644
--- a/src/Mvc/Mvc.Core/src/Routing/ControllerRequestDelegateFactory.cs
+++ b/src/Mvc/Mvc.Core/src/Routing/ControllerRequestDelegateFactory.cs
@@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// Super happy path (well assuming nobody cares about filters :O)
if (actionDescriptor is ControllerActionDescriptor ca && ca.FilterDescriptors.Any(a => a.Filter is IApiBehaviorMetadata) && dataTokens == null)
{
- var entry = _controllerActionInvokerCache.GetCachedEntry(ca);
+ var entry = _controllerActionInvokerCache.CreateEntry(ca);
return async context =>
{
@@ -66,8 +66,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
{
Dictionary<string, object> arguments = null;
- if (actionDescriptor.BoundProperties.Count > 0 ||
- actionDescriptor.Parameters.Count > 0)
+ if (entry.ControllerBinderDelegate != null)
{
// Allocation :(
arguments = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);