Merge pull request #8524 from aspnet/rynowak/endpoint-selector-master
Rynowak/endpoint selector master
This commit is contained in:
commit
e9c7b08d10
|
|
@ -48,8 +48,8 @@
|
||||||
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
|
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
|
||||||
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
|
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
|
||||||
<MicrosoftAspNetCoreResponseCachingPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreResponseCachingPackageVersion>
|
<MicrosoftAspNetCoreResponseCachingPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreResponseCachingPackageVersion>
|
||||||
<MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>
|
<MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>3.0.0-a-alpha1-endpoint-selector-master-17042</MicrosoftAspNetCoreRoutingAbstractionsPackageVersion>
|
||||||
<MicrosoftAspNetCoreRoutingPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreRoutingPackageVersion>
|
<MicrosoftAspNetCoreRoutingPackageVersion>3.0.0-a-alpha1-endpoint-selector-master-17042</MicrosoftAspNetCoreRoutingPackageVersion>
|
||||||
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
||||||
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||||
<MicrosoftAspNetCoreSessionPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreSessionPackageVersion>
|
<MicrosoftAspNetCoreSessionPackageVersion>3.0.0-alpha1-10549</MicrosoftAspNetCoreSessionPackageVersion>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
internal bool ShouldRunActionConstraints => _actionConstraintCache.CurrentCache.HasActionConstraints;
|
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.
|
// 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)
|
// set as valid. This is O(2n) vs O(n**2)
|
||||||
for (var i = 0; i < candidateSet.Count; i++)
|
for (var i = 0; i < candidateSet.Count; i++)
|
||||||
{
|
{
|
||||||
candidateSet[i].IsValidCandidate = false;
|
candidateSet.SetValidity(i, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalMatches != null)
|
if (finalMatches != null)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < finalMatches.Count; i++)
|
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
|
// Perf: Avoid allocations
|
||||||
for (var i = 0; i < candidateSet.Count; i++)
|
for (var i = 0; i < candidateSet.Count; i++)
|
||||||
{
|
{
|
||||||
ref var candidate = ref candidateSet[i];
|
if (candidateSet.IsValidCandidate(i))
|
||||||
if (candidate.IsValidCandidate)
|
|
||||||
{
|
{
|
||||||
|
ref var candidate = ref candidateSet[i];
|
||||||
if (score != null && score != candidate.Score)
|
if (score != null && score != candidate.Score)
|
||||||
{
|
{
|
||||||
// This is the end of a group.
|
// This is the end of a group.
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
public async Task Endpoints_InvokeReturnedEndpoint_ActionInvokerProviderCalled()
|
public async Task Endpoints_InvokeReturnedEndpoint_ActionInvokerProviderCalled()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var endpointFeature = new EndpointFeature
|
var endpointFeature = new EndpointSelectorContext
|
||||||
{
|
{
|
||||||
RouteValues = new RouteValueDictionary()
|
RouteValues = new RouteValueDictionary()
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
|
|
||||||
var feature = new EndpointFeature
|
var feature = new EndpointSelectorContext
|
||||||
{
|
{
|
||||||
RouteValues = new RouteValueDictionary(ambientValues)
|
RouteValues = new RouteValueDictionary(ambientValues)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var urlHelper = CreateUrlHelper(new[] { endpoint1, endpoint2 });
|
var urlHelper = CreateUrlHelper(new[] { endpoint1, endpoint2 });
|
||||||
|
|
||||||
// Set the endpoint feature and current context just as a normal request to MVC app would be
|
// 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<IEndpointFeature>(endpointFeature);
|
urlHelper.ActionContext.HttpContext.Features.Set<IEndpointFeature>(endpointFeature);
|
||||||
urlHelper.ActionContext.HttpContext.Features.Set<IRouteValuesFeature>(endpointFeature);
|
urlHelper.ActionContext.HttpContext.Features.Set<IRouteValuesFeature>(endpointFeature);
|
||||||
endpointFeature.Endpoint = endpoint1;
|
endpointFeature.Endpoint = endpoint1;
|
||||||
|
|
@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
protected override IUrlHelper CreateUrlHelper(ActionContext actionContext)
|
protected override IUrlHelper CreateUrlHelper(ActionContext actionContext)
|
||||||
{
|
{
|
||||||
var httpContext = actionContext.HttpContext;
|
var httpContext = actionContext.HttpContext;
|
||||||
httpContext.Features.Set<IEndpointFeature>(new EndpointFeature()
|
httpContext.Features.Set<IEndpointFeature>(new EndpointSelectorContext()
|
||||||
{
|
{
|
||||||
Endpoint = new Endpoint(
|
Endpoint = new Endpoint(
|
||||||
context => Task.CompletedTask,
|
context => Task.CompletedTask,
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
|
|
||||||
var feature = new EndpointFeature
|
var feature = new EndpointSelectorContext
|
||||||
{
|
{
|
||||||
RouteValues = new RouteValueDictionary(ambientValues)
|
RouteValues = new RouteValueDictionary(ambientValues)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var selector = CreateSelector(actions);
|
var selector = CreateSelector(actions);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(new DefaultHttpContext(), new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(new DefaultHttpContext(), new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(candidateSet[0].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(0));
|
||||||
Assert.True(candidateSet[1].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -68,11 +68,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(candidateSet[0].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(0));
|
||||||
Assert.False(candidateSet[1].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -103,11 +103,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(candidateSet[0].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(0));
|
||||||
Assert.False(candidateSet[1].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -139,11 +139,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(candidateSet[0].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(0));
|
||||||
Assert.False(candidateSet[1].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to ordering of stages, the first action will be better.
|
// Due to ordering of stages, the first action will be better.
|
||||||
|
|
@ -174,11 +174,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(candidateSet[0].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(0));
|
||||||
Assert.False(candidateSet[1].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -205,19 +205,19 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
|
|
||||||
var actions = new ActionDescriptor[] { best, another, worst };
|
var actions = new ActionDescriptor[] { best, another, worst };
|
||||||
var candidateSet = CreateCandidateSet(actions);
|
var candidateSet = CreateCandidateSet(actions);
|
||||||
candidateSet[0].IsValidCandidate = false;
|
candidateSet.SetValidity(0, false);
|
||||||
candidateSet[1].IsValidCandidate = false;
|
candidateSet.SetValidity(1, false);
|
||||||
|
|
||||||
var selector = CreateSelector(actions);
|
var selector = CreateSelector(actions);
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(candidateSet[0].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(0));
|
||||||
Assert.False(candidateSet[1].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(1));
|
||||||
Assert.True(candidateSet[2].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -247,12 +247,12 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(candidateSet[0].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(0));
|
||||||
Assert.True(candidateSet[1].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(1));
|
||||||
Assert.False(candidateSet[2].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to ordering of stages, the first action will be better.
|
// Due to ordering of stages, the first action will be better.
|
||||||
|
|
@ -288,11 +288,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(candidateSet[0].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(0));
|
||||||
Assert.False(candidateSet[1].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -329,12 +329,12 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
var httpContext = CreateHttpContext("POST");
|
var httpContext = CreateHttpContext("POST");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await selector.ApplyAsync(httpContext, new EndpointFeature(), candidateSet);
|
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(candidateSet[0].IsValidCandidate);
|
Assert.True(candidateSet.IsValidCandidate(0));
|
||||||
Assert.False(candidateSet[1].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(1));
|
||||||
Assert.False(candidateSet[2].IsValidCandidate);
|
Assert.False(candidateSet.IsValidCandidate(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -452,18 +452,16 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
|
|
||||||
private static CandidateSet CreateCandidateSet(ActionDescriptor[] actions)
|
private static CandidateSet CreateCandidateSet(ActionDescriptor[] actions)
|
||||||
{
|
{
|
||||||
var candidateSet = new CandidateSet(
|
var values = new RouteValueDictionary[actions.Length];
|
||||||
actions.Select(CreateEndpoint).ToArray(),
|
|
||||||
new int[actions.Length]);
|
|
||||||
|
|
||||||
for (var i = 0; i < actions.Length; i++)
|
for (var i = 0; i < actions.Length; i++)
|
||||||
{
|
{
|
||||||
if (candidateSet[i].IsValidCandidate)
|
values[i] = new RouteValueDictionary();
|
||||||
{
|
|
||||||
candidateSet[i].Values = new RouteValueDictionary();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var candidateSet = new CandidateSet(
|
||||||
|
actions.Select(CreateEndpoint).ToArray(),
|
||||||
|
values,
|
||||||
|
new int[actions.Length]);
|
||||||
return candidateSet;
|
return candidateSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue