diff --git a/build/dependencies.props b/build/dependencies.props
index e8d06421c4..e47c6782ea 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -48,8 +48,8 @@
2.2.0-preview3-35359
2.2.0-preview3-35359
2.2.0-preview3-35359
- 2.2.0-preview3-35359
- 2.2.0-preview3-35359
+ 2.2.0-a-preview3-endpoint-selector-17041
+ 2.2.0-a-preview3-endpoint-selector-17041
2.2.0-preview3-35359
2.2.0-preview3-35359
2.2.0-preview3-35359
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Routing/ActionConstraintMatcherPolicy.cs b/src/Microsoft.AspNetCore.Mvc.Core/Routing/ActionConstraintMatcherPolicy.cs
index e03640b59c..488b15646b 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Routing/ActionConstraintMatcherPolicy.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Routing/ActionConstraintMatcherPolicy.cs
@@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// Internal for testing
internal bool ShouldRunActionConstraints => _actionConstraintCache.CurrentCache.HasActionConstraints;
- public Task ApplyAsync(HttpContext httpContext, EndpointFeature endpointFeature, CandidateSet candidateSet)
+ public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidateSet)
{
// PERF: we can skip over action constraints if there aren't any app-wide.
//
@@ -64,14 +64,14 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// set as valid. This is O(2n) vs O(n**2)
for (var i = 0; i < candidateSet.Count; i++)
{
- candidateSet[i].IsValidCandidate = false;
+ candidateSet.SetValidity(i, false);
}
if (finalMatches != null)
{
for (var i = 0; i < finalMatches.Count; i++)
{
- candidateSet[finalMatches[i].index].IsValidCandidate = true;
+ candidateSet.SetValidity(finalMatches[i].index, true);
}
}
}
@@ -91,9 +91,9 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// Perf: Avoid allocations
for (var i = 0; i < candidateSet.Count; i++)
{
- ref var candidate = ref candidateSet[i];
- if (candidate.IsValidCandidate)
+ if (candidateSet.IsValidCandidate(i))
{
+ ref var candidate = ref candidateSet[i];
if (score != null && score != candidate.Score)
{
// This is the end of a group.
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs
index 168ae2950f..d35dea52ca 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/MvcEndpointDataSourceTests.cs
@@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
public async Task Endpoints_InvokeReturnedEndpoint_ActionInvokerProviderCalled()
{
// Arrange
- var endpointFeature = new EndpointFeature
+ var endpointFeature = new EndpointSelectorContext
{
RouteValues = new RouteValueDictionary()
};
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ControllerLinkGeneratorExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ControllerLinkGeneratorExtensionsTest.cs
index 5d0f01fafb..29a197d67f 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ControllerLinkGeneratorExtensionsTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/ControllerLinkGeneratorExtensionsTest.cs
@@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Routing
{
var httpContext = new DefaultHttpContext();
- var feature = new EndpointFeature
+ var feature = new EndpointSelectorContext
{
RouteValues = new RouteValueDictionary(ambientValues)
};
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs
index 6853dd7180..bf423d775e 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/EndpointRoutingUrlHelperTest.cs
@@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var urlHelper = CreateUrlHelper(new[] { endpoint1, endpoint2 });
// Set the endpoint feature and current context just as a normal request to MVC app would be
- var endpointFeature = new EndpointFeature();
+ var endpointFeature = new EndpointSelectorContext();
urlHelper.ActionContext.HttpContext.Features.Set(endpointFeature);
urlHelper.ActionContext.HttpContext.Features.Set(endpointFeature);
endpointFeature.Endpoint = endpoint1;
@@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
protected override IUrlHelper CreateUrlHelper(ActionContext actionContext)
{
var httpContext = actionContext.HttpContext;
- httpContext.Features.Set(new EndpointFeature()
+ httpContext.Features.Set(new EndpointSelectorContext()
{
Endpoint = new Endpoint(
context => Task.CompletedTask,
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/PageLinkGeneratorExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/PageLinkGeneratorExtensionsTest.cs
index f07f150472..89531042f1 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/PageLinkGeneratorExtensionsTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Routing/PageLinkGeneratorExtensionsTest.cs
@@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Routing
{
var httpContext = new DefaultHttpContext();
- var feature = new EndpointFeature
+ var feature = new EndpointSelectorContext
{
RouteValues = new RouteValueDictionary(ambientValues)
};
diff --git a/test/Microsoft.AspNetCore.Mvc.Test/Routing/ActionConstraintMatcherPolicyTest.cs b/test/Microsoft.AspNetCore.Mvc.Test/Routing/ActionConstraintMatcherPolicyTest.cs
index 9889b12e1b..5210180832 100644
--- a/test/Microsoft.AspNetCore.Mvc.Test/Routing/ActionConstraintMatcherPolicyTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Test/Routing/ActionConstraintMatcherPolicyTest.cs
@@ -35,11 +35,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var selector = CreateSelector(actions);
// Act
- await selector.ApplyAsync(new DefaultHttpContext(), new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(new DefaultHttpContext(), new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.True(candidateSet[0].IsValidCandidate);
- Assert.True(candidateSet[1].IsValidCandidate);
+ Assert.True(candidateSet.IsValidCandidate(0));
+ Assert.True(candidateSet.IsValidCandidate(1));
}
[Fact]
@@ -68,11 +68,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.True(candidateSet[0].IsValidCandidate);
- Assert.False(candidateSet[1].IsValidCandidate);
+ Assert.True(candidateSet.IsValidCandidate(0));
+ Assert.False(candidateSet.IsValidCandidate(1));
}
[Fact]
@@ -103,11 +103,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.False(candidateSet[0].IsValidCandidate);
- Assert.False(candidateSet[1].IsValidCandidate);
+ Assert.False(candidateSet.IsValidCandidate(0));
+ Assert.False(candidateSet.IsValidCandidate(1));
}
[Fact]
@@ -139,11 +139,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.False(candidateSet[0].IsValidCandidate);
- Assert.False(candidateSet[1].IsValidCandidate);
+ Assert.False(candidateSet.IsValidCandidate(0));
+ Assert.False(candidateSet.IsValidCandidate(1));
}
// Due to ordering of stages, the first action will be better.
@@ -174,11 +174,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.True(candidateSet[0].IsValidCandidate);
- Assert.False(candidateSet[1].IsValidCandidate);
+ Assert.True(candidateSet.IsValidCandidate(0));
+ Assert.False(candidateSet.IsValidCandidate(1));
}
[Fact]
@@ -205,19 +205,19 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var actions = new ActionDescriptor[] { best, another, worst };
var candidateSet = CreateCandidateSet(actions);
- candidateSet[0].IsValidCandidate = false;
- candidateSet[1].IsValidCandidate = false;
+ candidateSet.SetValidity(0, false);
+ candidateSet.SetValidity(1, false);
var selector = CreateSelector(actions);
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.False(candidateSet[0].IsValidCandidate);
- Assert.False(candidateSet[1].IsValidCandidate);
- Assert.True(candidateSet[2].IsValidCandidate);
+ Assert.False(candidateSet.IsValidCandidate(0));
+ Assert.False(candidateSet.IsValidCandidate(1));
+ Assert.True(candidateSet.IsValidCandidate(2));
}
[Fact]
@@ -247,12 +247,12 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.False(candidateSet[0].IsValidCandidate);
- Assert.True(candidateSet[1].IsValidCandidate);
- Assert.False(candidateSet[2].IsValidCandidate);
+ Assert.False(candidateSet.IsValidCandidate(0));
+ Assert.True(candidateSet.IsValidCandidate(1));
+ Assert.False(candidateSet.IsValidCandidate(2));
}
// Due to ordering of stages, the first action will be better.
@@ -288,11 +288,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.True(candidateSet[0].IsValidCandidate);
- Assert.False(candidateSet[1].IsValidCandidate);
+ Assert.True(candidateSet.IsValidCandidate(0));
+ Assert.False(candidateSet.IsValidCandidate(1));
}
[Fact]
@@ -329,12 +329,12 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
- await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
+ await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
// Assert
- Assert.True(candidateSet[0].IsValidCandidate);
- Assert.False(candidateSet[1].IsValidCandidate);
- Assert.False(candidateSet[2].IsValidCandidate);
+ Assert.True(candidateSet.IsValidCandidate(0));
+ Assert.False(candidateSet.IsValidCandidate(1));
+ Assert.False(candidateSet.IsValidCandidate(2));
}
[Fact]
@@ -452,18 +452,16 @@ namespace Microsoft.AspNetCore.Mvc.Routing
private static CandidateSet CreateCandidateSet(ActionDescriptor[] actions)
{
- var candidateSet = new CandidateSet(
- actions.Select(CreateEndpoint).ToArray(),
- new int[actions.Length]);
-
+ var values = new RouteValueDictionary[actions.Length];
for (var i = 0; i < actions.Length; i++)
{
- if (candidateSet[i].IsValidCandidate)
- {
- candidateSet[i].Values = new RouteValueDictionary();
- }
+ values[i] = new RouteValueDictionary();
}
+ var candidateSet = new CandidateSet(
+ actions.Select(CreateEndpoint).ToArray(),
+ values,
+ new int[actions.Length]);
return candidateSet;
}