Merge pull request #650 from aspnet/release/2.2
automerge release/2.2 -> master
This commit is contained in:
commit
184dc270f4
20
Routing.sln
20
Routing.sln
|
|
@ -1,4 +1,5 @@
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.27106.3000
|
VisualStudioVersion = 15.0.27106.3000
|
||||||
MinimumVisualStudioVersion = 15.0.26730.03
|
MinimumVisualStudioVersion = 15.0.26730.03
|
||||||
|
|
@ -44,15 +45,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6DC6B416
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Routing.Performance", "benchmarks\Microsoft.AspNetCore.Routing.Performance\Microsoft.AspNetCore.Routing.Performance.csproj", "{F3D86714-4E64-41A6-9B36-A47B3683CF5D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Routing.Performance", "benchmarks\Microsoft.AspNetCore.Routing.Performance\Microsoft.AspNetCore.Routing.Performance.csproj", "{F3D86714-4E64-41A6-9B36-A47B3683CF5D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DispatcherSample.Web", "samples\DispatcherSample.Web\DispatcherSample.Web.csproj", "{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{D5F39F59-5725-4127-82E7-67028D006185}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{D5F39F59-5725-4127-82E7-67028D006185}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarkapps", "benchmarkapps", "{7F5914E2-C63F-4759-898E-462804357C90}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarkapps", "benchmarkapps", "{7F5914E2-C63F-4759-898E-462804357C90}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "benchmarkapps\Benchmarks\Benchmarks.csproj", "{91F47A60-9A78-4968-B10D-157D9BFAC37F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "benchmarkapps\Benchmarks\Benchmarks.csproj", "{91F47A60-9A78-4968-B10D-157D9BFAC37F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Swaggatherer", "benchmarks\Swaggatherer\Swaggatherer.csproj", "{990ECDEE-49DE-45E3-B0D9-DDEB9CFF6A9D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Swaggatherer", "benchmarks\Swaggatherer\Swaggatherer.csproj", "{990ECDEE-49DE-45E3-B0D9-DDEB9CFF6A9D}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
@ -154,18 +153,6 @@ Global
|
||||||
{F3D86714-4E64-41A6-9B36-A47B3683CF5D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{F3D86714-4E64-41A6-9B36-A47B3683CF5D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{F3D86714-4E64-41A6-9B36-A47B3683CF5D}.Release|x86.ActiveCfg = Release|Any CPU
|
{F3D86714-4E64-41A6-9B36-A47B3683CF5D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{F3D86714-4E64-41A6-9B36-A47B3683CF5D}.Release|x86.Build.0 = Release|Any CPU
|
{F3D86714-4E64-41A6-9B36-A47B3683CF5D}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{91F47A60-9A78-4968-B10D-157D9BFAC37F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{91F47A60-9A78-4968-B10D-157D9BFAC37F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{91F47A60-9A78-4968-B10D-157D9BFAC37F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{91F47A60-9A78-4968-B10D-157D9BFAC37F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{91F47A60-9A78-4968-B10D-157D9BFAC37F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
{91F47A60-9A78-4968-B10D-157D9BFAC37F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
|
@ -203,7 +190,6 @@ Global
|
||||||
{741B0B05-CE96-473B-B962-6B0A347DF79A} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
{741B0B05-CE96-473B-B962-6B0A347DF79A} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
||||||
{5C73140B-41F3-466F-A07B-3614E4D80DF9} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
{5C73140B-41F3-466F-A07B-3614E4D80DF9} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
||||||
{F3D86714-4E64-41A6-9B36-A47B3683CF5D} = {D5F39F59-5725-4127-82E7-67028D006185}
|
{F3D86714-4E64-41A6-9B36-A47B3683CF5D} = {D5F39F59-5725-4127-82E7-67028D006185}
|
||||||
{4EBE7A6F-3183-4A7D-B3D7-A6A9EC3867A5} = {C3ADD55B-B9C7-4061-8AD4-6A70D1AE3B2E}
|
|
||||||
{91F47A60-9A78-4968-B10D-157D9BFAC37F} = {7F5914E2-C63F-4759-898E-462804357C90}
|
{91F47A60-9A78-4968-B10D-157D9BFAC37F} = {7F5914E2-C63F-4759-898E-462804357C90}
|
||||||
{990ECDEE-49DE-45E3-B0D9-DDEB9CFF6A9D} = {D5F39F59-5725-4127-82E7-67028D006185}
|
{990ECDEE-49DE-45E3-B0D9-DDEB9CFF6A9D} = {D5F39F59-5725-4127-82E7-67028D006185}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
|
|
||||||
|
|
@ -29,22 +29,22 @@ namespace Benchmarks
|
||||||
.UseKestrel();
|
.UseKestrel();
|
||||||
|
|
||||||
var scenario = config["scenarios"]?.ToLower();
|
var scenario = config["scenarios"]?.ToLower();
|
||||||
if (scenario == "plaintextdispatcher")
|
if (scenario == "plaintextdispatcher" || scenario == "plaintextglobalrouting")
|
||||||
{
|
{
|
||||||
webHostBuilder.UseStartup<StartupUsingDispatcher>();
|
webHostBuilder.UseStartup<StartupUsingGlobalRouting>();
|
||||||
// for testing
|
// for testing
|
||||||
webHostBuilder.UseSetting("Startup", nameof(StartupUsingDispatcher));
|
webHostBuilder.UseSetting("Startup", nameof(StartupUsingGlobalRouting));
|
||||||
}
|
}
|
||||||
else if (scenario == "plaintextrouting")
|
else if (scenario == "plaintextrouting" || scenario == "plaintextrouter")
|
||||||
{
|
{
|
||||||
webHostBuilder.UseStartup<StartupUsingRouting>();
|
webHostBuilder.UseStartup<StartupUsingRouter>();
|
||||||
// for testing
|
// for testing
|
||||||
webHostBuilder.UseSetting("Startup", nameof(StartupUsingRouting));
|
webHostBuilder.UseSetting("Startup", nameof(StartupUsingRouter));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
$"Invalid scenario '{scenario}'. Allowed scenarios are PlaintextDispatcher and PlaintextRouting");
|
$"Invalid scenario '{scenario}'. Allowed scenarios are PlaintextGlobalRouting and PlaintextRouter");
|
||||||
}
|
}
|
||||||
|
|
||||||
return webHostBuilder;
|
return webHostBuilder;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Benchmarks
|
namespace Benchmarks
|
||||||
{
|
{
|
||||||
public class StartupUsingDispatcher
|
public class StartupUsingGlobalRouting
|
||||||
{
|
{
|
||||||
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace Benchmarks
|
||||||
{
|
{
|
||||||
services.AddRouting();
|
services.AddRouting();
|
||||||
|
|
||||||
services.AddDispatcher(options =>
|
services.Configure<EndpointOptions>(options =>
|
||||||
{
|
{
|
||||||
options.DataSources.Add(new DefaultEndpointDataSource(new[]
|
options.DataSources.Add(new DefaultEndpointDataSource(new[]
|
||||||
{
|
{
|
||||||
|
|
@ -43,7 +43,7 @@ namespace Benchmarks
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app)
|
public void Configure(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
app.UseDispatcher();
|
app.UseGlobalRouting();
|
||||||
|
|
||||||
app.UseEndpoint();
|
app.UseEndpoint();
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace Benchmarks
|
namespace Benchmarks
|
||||||
{
|
{
|
||||||
public class StartupUsingRouting
|
public class StartupUsingRouter
|
||||||
{
|
{
|
||||||
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
||||||
|
|
||||||
|
|
@ -16,7 +16,13 @@
|
||||||
"PlaintextRouting": {
|
"PlaintextRouting": {
|
||||||
"Path": "/plaintext"
|
"Path": "/plaintext"
|
||||||
},
|
},
|
||||||
|
"PlaintextRouter": {
|
||||||
|
"Path": "/plaintext"
|
||||||
|
},
|
||||||
"PlaintextDispatcher": {
|
"PlaintextDispatcher": {
|
||||||
"Path": "/plaintext"
|
"Path": "/plaintext"
|
||||||
|
},
|
||||||
|
"PlaintextGlobalRouting": {
|
||||||
|
"Path": "/plaintext"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
var sample = _samples[i];
|
var sample = _samples[i];
|
||||||
var httpContext = Requests[sample];
|
var httpContext = Requests[sample];
|
||||||
|
|
||||||
// This is required to make the legacy router implementation work with dispatcher.
|
// This is required to make the legacy router implementation work with global routing.
|
||||||
httpContext.Features.Set<IEndpointFeature>(feature);
|
httpContext.Features.Set<IEndpointFeature>(feature);
|
||||||
|
|
||||||
await _tree.MatchAsync(httpContext, feature);
|
await _tree.MatchAsync(httpContext, feature);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
services.AddRouting();
|
services.AddRouting();
|
||||||
services.AddDispatcher();
|
|
||||||
return services.BuildServiceProvider();
|
return services.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
{
|
{
|
||||||
var httpContext = Requests[i];
|
var httpContext = Requests[i];
|
||||||
|
|
||||||
// This is required to make the legacy router implementation work with dispatcher.
|
// This is required to make the legacy router implementation work with global routing.
|
||||||
httpContext.Features.Set<IEndpointFeature>(feature);
|
httpContext.Features.Set<IEndpointFeature>(feature);
|
||||||
|
|
||||||
await _tree.MatchAsync(httpContext, feature);
|
await _tree.MatchAsync(httpContext, feature);
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
|
|
||||||
var httpContext = Requests[0];
|
var httpContext = Requests[0];
|
||||||
|
|
||||||
// This is required to make the legacy router implementation work with dispatcher.
|
// This is required to make the legacy router implementation work with global routing.
|
||||||
httpContext.Features.Set<IEndpointFeature>(feature);
|
httpContext.Features.Set<IEndpointFeature>(feature);
|
||||||
|
|
||||||
await _tree.MatchAsync(httpContext, feature);
|
await _tree.MatchAsync(httpContext, feature);
|
||||||
|
|
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
var feature = _feature;
|
var feature = _feature;
|
||||||
var httpContext = Requests[0];
|
var httpContext = Requests[0];
|
||||||
|
|
||||||
// This is required to make the legacy router implementation work with dispatcher.
|
// This is required to make the legacy router implementation work with global routing.
|
||||||
httpContext.Features.Set<IEndpointFeature>(feature);
|
httpContext.Features.Set<IEndpointFeature>(feature);
|
||||||
|
|
||||||
await _route.MatchAsync(httpContext, feature);
|
await _route.MatchAsync(httpContext, feature);
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks>netcoreapp2.2</TargetFrameworks>
|
|
||||||
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net461</TargetFrameworks>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
// 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 Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
|
|
||||||
namespace DispatcherSample.Web
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
var webHost = GetWebHostBuilder().Build();
|
|
||||||
webHost.Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For unit testing
|
|
||||||
public static IWebHostBuilder GetWebHostBuilder()
|
|
||||||
{
|
|
||||||
return new WebHostBuilder()
|
|
||||||
.UseKestrel()
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseStartup<Startup>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Globalization;
|
||||||
using Microsoft.AspNetCore.Routing.Matchers;
|
using Microsoft.AspNetCore.Routing.Matchers;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace DispatcherSample.Web
|
namespace RoutingSample.Web
|
||||||
{
|
{
|
||||||
internal class EndsWithStringMatchProcessor : MatchProcessorBase
|
internal class EndsWithStringMatchProcessor : MatchProcessorBase
|
||||||
{
|
{
|
||||||
|
|
@ -44,14 +44,14 @@ namespace RoutingSample.Web
|
||||||
var lastCharacter = requestPath[_prefix.Length];
|
var lastCharacter = requestPath[_prefix.Length];
|
||||||
if (lastCharacter != '/' && lastCharacter != '#' && lastCharacter != '?')
|
if (lastCharacter != '/' && lastCharacter != '#' && lastCharacter != '?')
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Handler = _target.GetRequestHandler(context.HttpContext, context.RouteData);
|
context.Handler = _target.GetRequestHandler(context.HttpContext, context.RouteData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(0);
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VirtualPathData GetVirtualPath(VirtualPathContext context)
|
public VirtualPathData GetVirtualPath(VirtualPathContext context)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
||||||
|
|
@ -8,19 +9,57 @@ namespace RoutingSample.Web
|
||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
|
public static readonly string GlobalRoutingScenario = "globalrouting";
|
||||||
|
public static readonly string RouterScenario = "router";
|
||||||
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var webHost = GetWebHostBuilder().Build();
|
var webHost = GetWebHostBuilder(args).Build();
|
||||||
webHost.Run();
|
webHost.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// For unit testing
|
// For unit testing
|
||||||
public static IWebHostBuilder GetWebHostBuilder()
|
public static IWebHostBuilder GetWebHostBuilder(string[] args)
|
||||||
{
|
{
|
||||||
|
string scenario;
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Choose a sample to run:");
|
||||||
|
Console.WriteLine($"1. {GlobalRoutingScenario}");
|
||||||
|
Console.WriteLine($"2. {RouterScenario}");
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
scenario = Console.ReadLine();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scenario = args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
Type startupType;
|
||||||
|
switch (scenario)
|
||||||
|
{
|
||||||
|
case "1":
|
||||||
|
case "globalrouting":
|
||||||
|
startupType = typeof(UseGlobalRoutingStartup);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "2":
|
||||||
|
case "router":
|
||||||
|
startupType = typeof(UseRouterStartup);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Console.WriteLine($"unknown scenario {scenario}");
|
||||||
|
Console.WriteLine($"usage: dotnet run -- ({GlobalRoutingScenario}|{RouterScenario})");
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return new WebHostBuilder()
|
return new WebHostBuilder()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseStartup<Startup>();
|
.UseStartup(startupType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
@ -11,11 +10,11 @@ using Microsoft.AspNetCore.Routing.Matchers;
|
||||||
using Microsoft.AspNetCore.Routing.Patterns;
|
using Microsoft.AspNetCore.Routing.Patterns;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace DispatcherSample.Web
|
namespace RoutingSample.Web
|
||||||
{
|
{
|
||||||
public class Startup
|
public class UseGlobalRoutingStartup
|
||||||
{
|
{
|
||||||
private static readonly byte[] _homePayload = Encoding.UTF8.GetBytes("Dispatcher sample endpoints:" + Environment.NewLine + "/plaintext");
|
private static readonly byte[] _homePayload = Encoding.UTF8.GetBytes("Global Routing sample endpoints:" + Environment.NewLine + "/plaintext");
|
||||||
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
||||||
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
|
@ -26,11 +25,11 @@ namespace DispatcherSample.Web
|
||||||
{
|
{
|
||||||
options.ConstraintMap.Add("endsWith", typeof(EndsWithStringMatchProcessor));
|
options.ConstraintMap.Add("endsWith", typeof(EndsWithStringMatchProcessor));
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddDispatcher(options =>
|
services.Configure<EndpointOptions>(options =>
|
||||||
{
|
{
|
||||||
options.DataSources.Add(new DefaultEndpointDataSource(new[]
|
options.DataSources.Add(new DefaultEndpointDataSource(new[]
|
||||||
{
|
{
|
||||||
new MatcherEndpoint((next) => (httpContext) =>
|
new MatcherEndpoint((next) => (httpContext) =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
|
|
@ -83,13 +82,13 @@ namespace DispatcherSample.Web
|
||||||
0,
|
0,
|
||||||
EndpointMetadataCollection.Empty,
|
EndpointMetadataCollection.Empty,
|
||||||
"withoptionalconstraints"),
|
"withoptionalconstraints"),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app)
|
public void Configure(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
app.UseDispatcher();
|
app.UseGlobalRouting();
|
||||||
|
|
||||||
// Imagine some more stuff here...
|
// Imagine some more stuff here...
|
||||||
|
|
||||||
|
|
@ -11,7 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace RoutingSample.Web
|
namespace RoutingSample.Web
|
||||||
{
|
{
|
||||||
public class Startup
|
public class UseRouterStartup
|
||||||
{
|
{
|
||||||
private static readonly TimeSpan RegexMatchTimeout = TimeSpan.FromSeconds(10);
|
private static readonly TimeSpan RegexMatchTimeout = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
// 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;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
|
||||||
using Microsoft.AspNetCore.Routing.Internal;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
|
||||||
{
|
|
||||||
public static class DispatcherApplicationBuilderExtensions
|
|
||||||
{
|
|
||||||
private const string DispatcherRegisteredKey = "__DispatcherMiddlewareRegistered";
|
|
||||||
|
|
||||||
public static IApplicationBuilder UseDispatcher(this IApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
VerifyDispatcherIsRegistered(builder);
|
|
||||||
|
|
||||||
builder.Properties[DispatcherRegisteredKey] = true;
|
|
||||||
|
|
||||||
return builder.UseMiddleware<DispatcherMiddleware>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IApplicationBuilder UseEndpoint(this IApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
VerifyDispatcherIsRegistered(builder);
|
|
||||||
|
|
||||||
if (!builder.Properties.TryGetValue(DispatcherRegisteredKey, out _))
|
|
||||||
{
|
|
||||||
var message = $"{nameof(DispatcherMiddleware)} must be added to the request execution pipeline before {nameof(EndpointMiddleware)}. " +
|
|
||||||
$"Please add {nameof(DispatcherMiddleware)} by calling '{nameof(IApplicationBuilder)}.{nameof(UseDispatcher)}' inside the call to 'Configure(...)' in the application startup code.";
|
|
||||||
|
|
||||||
throw new InvalidOperationException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.UseMiddleware<EndpointMiddleware>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void VerifyDispatcherIsRegistered(IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
// Verify if AddDispatcher was done before calling UseDispatcher/UseEndpoint
|
|
||||||
// We use the DispatcherMarkerService to make sure if all the services were added.
|
|
||||||
if (app.ApplicationServices.GetService(typeof(DispatcherMarkerService)) == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException(Resources.FormatUnableToFindServices(
|
|
||||||
nameof(IServiceCollection),
|
|
||||||
nameof(DispatcherServiceCollectionExtensions.AddDispatcher),
|
|
||||||
"ConfigureServices(...)"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
// 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;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Microsoft.AspNetCore.Routing.Internal;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Builder
|
||||||
|
{
|
||||||
|
public static class GlobalRoutingApplicationBuilderExtensions
|
||||||
|
{
|
||||||
|
private const string GlobalRoutingRegisteredKey = "__GlobalRoutingMiddlewareRegistered";
|
||||||
|
|
||||||
|
// This is provided temporarily until we can remove usages of it from MVC.
|
||||||
|
public static IApplicationBuilder UseDispatcher(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
return UseGlobalRouting(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IApplicationBuilder UseGlobalRouting(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
VerifyRoutingIsRegistered(builder);
|
||||||
|
|
||||||
|
builder.Properties[GlobalRoutingRegisteredKey] = true;
|
||||||
|
|
||||||
|
return builder.UseMiddleware<GlobalRoutingMiddleware>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IApplicationBuilder UseEndpoint(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
VerifyRoutingIsRegistered(builder);
|
||||||
|
|
||||||
|
if (!builder.Properties.TryGetValue(GlobalRoutingRegisteredKey, out _))
|
||||||
|
{
|
||||||
|
var message = $"{nameof(GlobalRoutingMiddleware)} must be added to the request execution pipeline before {nameof(EndpointMiddleware)}. " +
|
||||||
|
$"Please add {nameof(GlobalRoutingMiddleware)} by calling '{nameof(IApplicationBuilder)}.{nameof(UseGlobalRouting)}' inside the call to 'Configure(...)' in the application startup code.";
|
||||||
|
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.UseMiddleware<EndpointMiddleware>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void VerifyRoutingIsRegistered(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
// Verify if AddRouting was done before calling UseGlobalRouting/UseEndpoint
|
||||||
|
// We use the RoutingMarkerService to make sure if all the services were added.
|
||||||
|
if (app.ApplicationServices.GetService(typeof(RoutingMarkerService)) == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(Resources.FormatUnableToFindServices(
|
||||||
|
nameof(IServiceCollection),
|
||||||
|
nameof(RoutingServiceCollectionExtensions.AddRouting),
|
||||||
|
"ConfigureServices(...)"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -69,8 +69,8 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
foreach (var dataSource in _dataSources)
|
foreach (var dataSource in _dataSources)
|
||||||
{
|
{
|
||||||
Extensions.Primitives.ChangeToken.OnChange(
|
Extensions.Primitives.ChangeToken.OnChange(
|
||||||
() => dataSource.ChangeToken,
|
dataSource.GetChangeToken,
|
||||||
() => HandleChange());
|
HandleChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
var changeToken = _dataSource.ChangeToken;
|
var changeToken = _dataSource.GetChangeToken();
|
||||||
_value = _initializeCore(_dataSource.Endpoints);
|
_value = _initializeCore(_dataSource.Endpoints);
|
||||||
|
|
||||||
changeToken.RegisterChangeCallback(_initializerWithState, null);
|
changeToken.RegisterChangeCallback(_initializerWithState, null);
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
internal class ConfigureDispatcherOptions : IConfigureOptions<DispatcherOptions>
|
internal class ConfigureEndpointOptions : IConfigureOptions<EndpointOptions>
|
||||||
{
|
{
|
||||||
private readonly IEnumerable<EndpointDataSource> _dataSources;
|
private readonly IEnumerable<EndpointDataSource> _dataSources;
|
||||||
|
|
||||||
public ConfigureDispatcherOptions(IEnumerable<EndpointDataSource> dataSources)
|
public ConfigureEndpointOptions(IEnumerable<EndpointDataSource> dataSources)
|
||||||
{
|
{
|
||||||
if (dataSources == null)
|
if (dataSources == null)
|
||||||
{
|
{
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
_dataSources = dataSources;
|
_dataSources = dataSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(DispatcherOptions options)
|
public void Configure(EndpointOptions options)
|
||||||
{
|
{
|
||||||
if (options == null)
|
if (options == null)
|
||||||
{
|
{
|
||||||
|
|
@ -2,19 +2,14 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.AspNetCore.Routing.EndpointConstraints;
|
|
||||||
using Microsoft.AspNetCore.Routing.EndpointFinders;
|
|
||||||
using Microsoft.AspNetCore.Routing.Internal;
|
|
||||||
using Microsoft.AspNetCore.Routing.Matchers;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
|
// This whole class is temporary until we can remove its usage from MVC
|
||||||
public static class DispatcherServiceCollectionExtensions
|
public static class DispatcherServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
|
// This whole class is temporary until we can remove its usage from MVC
|
||||||
public static IServiceCollection AddDispatcher(this IServiceCollection services)
|
public static IServiceCollection AddDispatcher(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
if (services == null)
|
if (services == null)
|
||||||
|
|
@ -22,53 +17,21 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
throw new ArgumentNullException(nameof(services));
|
throw new ArgumentNullException(nameof(services));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect all data sources from DI.
|
return services.AddRouting();
|
||||||
services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<DispatcherOptions>, ConfigureDispatcherOptions>());
|
|
||||||
|
|
||||||
// Allow global access to the list of endpoints.
|
|
||||||
services.TryAddSingleton<CompositeEndpointDataSource>(s =>
|
|
||||||
{
|
|
||||||
var options = s.GetRequiredService<IOptions<DispatcherOptions>>();
|
|
||||||
return new CompositeEndpointDataSource(options.Value.DataSources);
|
|
||||||
});
|
|
||||||
|
|
||||||
//
|
|
||||||
// Default matcher implementation
|
|
||||||
//
|
|
||||||
services.TryAddSingleton<MatchProcessorFactory, DefaultMatchProcessorFactory>();
|
|
||||||
services.TryAddSingleton<MatcherFactory, DfaMatcherFactory>();
|
|
||||||
services.TryAddTransient<DfaMatcherBuilder>();
|
|
||||||
|
|
||||||
// Link generation related services
|
|
||||||
services.TryAddSingleton<IEndpointFinder<string>, NameBasedEndpointFinder>();
|
|
||||||
services.TryAddSingleton<IEndpointFinder<RouteValuesBasedEndpointFinderContext>, RouteValuesBasedEndpointFinder>();
|
|
||||||
services.TryAddSingleton<LinkGenerator, DefaultLinkGenerator>();
|
|
||||||
//
|
|
||||||
// Endpoint Selection
|
|
||||||
//
|
|
||||||
services.TryAddSingleton<EndpointSelector>();
|
|
||||||
services.TryAddSingleton<EndpointConstraintCache>();
|
|
||||||
|
|
||||||
// Will be cached by the EndpointSelector
|
|
||||||
services.TryAddEnumerable(
|
|
||||||
ServiceDescriptor.Transient<IEndpointConstraintProvider, DefaultEndpointConstraintProvider>());
|
|
||||||
|
|
||||||
services.TryAddSingleton(typeof(DispatcherMarkerService));
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddDispatcher(this IServiceCollection services, Action<DispatcherOptions> configuration)
|
// This whole class is temporary until we can remove its usage from MVC
|
||||||
|
public static IServiceCollection AddDispatcher(this IServiceCollection services, Action<EndpointOptions> configuration)
|
||||||
{
|
{
|
||||||
if (services == null)
|
if (services == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(services));
|
throw new ArgumentNullException(nameof(services));
|
||||||
}
|
}
|
||||||
|
|
||||||
services.AddDispatcher();
|
services.AddRouting();
|
||||||
if (configuration != null)
|
if (configuration != null)
|
||||||
{
|
{
|
||||||
services.Configure<DispatcherOptions>(configuration);
|
services.Configure<EndpointOptions>(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,15 @@
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.AspNetCore.Routing.Constraints;
|
using Microsoft.AspNetCore.Routing.Constraints;
|
||||||
|
using Microsoft.AspNetCore.Routing.EndpointConstraints;
|
||||||
|
using Microsoft.AspNetCore.Routing.EndpointFinders;
|
||||||
using Microsoft.AspNetCore.Routing.Internal;
|
using Microsoft.AspNetCore.Routing.Internal;
|
||||||
using Microsoft.AspNetCore.Routing.Matchers;
|
using Microsoft.AspNetCore.Routing.Matchers;
|
||||||
using Microsoft.AspNetCore.Routing.Tree;
|
using Microsoft.AspNetCore.Routing.Tree;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.ObjectPool;
|
using Microsoft.Extensions.ObjectPool;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
|
|
@ -49,6 +52,37 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
|
|
||||||
services.TryAddSingleton(typeof(RoutingMarkerService));
|
services.TryAddSingleton(typeof(RoutingMarkerService));
|
||||||
|
|
||||||
|
// Collect all data sources from DI.
|
||||||
|
services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<EndpointOptions>, ConfigureEndpointOptions>());
|
||||||
|
|
||||||
|
// Allow global access to the list of endpoints.
|
||||||
|
services.TryAddSingleton<CompositeEndpointDataSource>(s =>
|
||||||
|
{
|
||||||
|
var options = s.GetRequiredService<IOptions<EndpointOptions>>();
|
||||||
|
return new CompositeEndpointDataSource(options.Value.DataSources);
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default matcher implementation
|
||||||
|
//
|
||||||
|
services.TryAddSingleton<MatchProcessorFactory, DefaultMatchProcessorFactory>();
|
||||||
|
services.TryAddSingleton<MatcherFactory, DfaMatcherFactory>();
|
||||||
|
services.TryAddTransient<DfaMatcherBuilder>();
|
||||||
|
|
||||||
|
// Link generation related services
|
||||||
|
services.TryAddSingleton<IEndpointFinder<string>, NameBasedEndpointFinder>();
|
||||||
|
services.TryAddSingleton<IEndpointFinder<RouteValuesBasedEndpointFinderContext>, RouteValuesBasedEndpointFinder>();
|
||||||
|
services.TryAddSingleton<LinkGenerator, DefaultLinkGenerator>();
|
||||||
|
//
|
||||||
|
// Endpoint Selection
|
||||||
|
//
|
||||||
|
services.TryAddSingleton<EndpointSelector>();
|
||||||
|
services.TryAddSingleton<EndpointConstraintCache>();
|
||||||
|
|
||||||
|
// Will be cached by the EndpointSelector
|
||||||
|
services.TryAddEnumerable(
|
||||||
|
ServiceDescriptor.Transient<IEndpointConstraintProvider, DefaultEndpointConstraintProvider>());
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,15 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
public abstract class EndpointDataSource
|
public abstract class EndpointDataSource
|
||||||
{
|
{
|
||||||
public abstract IChangeToken ChangeToken { get; }
|
public virtual IChangeToken ChangeToken { get; }
|
||||||
|
|
||||||
|
// Plan is to replace ChangeToken property with GetChangeToken
|
||||||
|
// Temporarily have both to avoid breaking MVC
|
||||||
|
// https://github.com/aspnet/Routing/issues/634
|
||||||
|
public virtual IChangeToken GetChangeToken()
|
||||||
|
{
|
||||||
|
return ChangeToken;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract IReadOnlyList<Endpoint> Endpoints { get; }
|
public abstract IReadOnlyList<Endpoint> Endpoints { get; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var feature = httpContext.Features.Get<IEndpointFeature>();
|
var feature = httpContext.Features.Get<IEndpointFeature>();
|
||||||
if (feature == null)
|
if (feature == null)
|
||||||
{
|
{
|
||||||
var message = $"Unable to execute an endpoint because the {nameof(DispatcherMiddleware)} was not run for this request. " +
|
var message = $"Unable to execute an endpoint because the {nameof(GlobalRoutingMiddleware)} was not run for this request. " +
|
||||||
$"Ensure {nameof(DispatcherMiddleware)} is added to the request execution pipeline before {nameof(EndpointMiddleware)} in application startup code.";
|
$"Ensure {nameof(GlobalRoutingMiddleware)} is added to the request execution pipeline before {nameof(EndpointMiddleware)} in application startup code.";
|
||||||
|
|
||||||
throw new InvalidOperationException(message);
|
throw new InvalidOperationException(message);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
public class DispatcherOptions
|
public class EndpointOptions
|
||||||
{
|
{
|
||||||
public IList<EndpointDataSource> DataSources { get; } = new List<EndpointDataSource>();
|
public IList<EndpointDataSource> DataSources { get; } = new List<EndpointDataSource>();
|
||||||
}
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
internal sealed class DispatcherMiddleware
|
internal sealed class GlobalRoutingMiddleware
|
||||||
{
|
{
|
||||||
private readonly MatcherFactory _matcherFactory;
|
private readonly MatcherFactory _matcherFactory;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
@ -20,10 +20,10 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
private Task<Matcher> _initializationTask;
|
private Task<Matcher> _initializationTask;
|
||||||
|
|
||||||
public DispatcherMiddleware(
|
public GlobalRoutingMiddleware(
|
||||||
MatcherFactory matcherFactory,
|
MatcherFactory matcherFactory,
|
||||||
CompositeEndpointDataSource endpointDataSource,
|
CompositeEndpointDataSource endpointDataSource,
|
||||||
ILogger<DispatcherMiddleware> logger,
|
ILogger<GlobalRoutingMiddleware> logger,
|
||||||
RequestDelegate next)
|
RequestDelegate next)
|
||||||
{
|
{
|
||||||
if (matcherFactory == null)
|
if (matcherFactory == null)
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
// 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 Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.Internal
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A marker class used to determine if all the dispatcher services were added
|
|
||||||
/// to the <see cref="IServiceCollection"/> before dispatcher is configured.
|
|
||||||
/// </summary>
|
|
||||||
internal class DispatcherMarkerService
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface for components that can select an <see cref="Endpoint"/> given the current request, as part
|
/// An interface for components that can select an <see cref="Endpoint"/> given the current request, as part
|
||||||
/// of the execution of <see cref="DispatcherMiddleware"/>.
|
/// of the execution of <see cref="GlobalRoutingMiddleware"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract class Matcher
|
internal abstract class Matcher
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
// Register for changes in endpoints
|
// Register for changes in endpoints
|
||||||
Extensions.Primitives.ChangeToken.OnChange(
|
Extensions.Primitives.ChangeToken.OnChange(
|
||||||
() => _endpointDataSource.ChangeToken,
|
_endpointDataSource.GetChangeToken,
|
||||||
() => HandleChange());
|
HandleChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Endpoint> FindEndpoints(RouteValuesBasedEndpointFinderContext context)
|
public IEnumerable<Endpoint> FindEndpoints(RouteValuesBasedEndpointFinderContext context)
|
||||||
|
|
@ -70,8 +70,8 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
// re-register the callback as the change token is one time use only and a new change token
|
// re-register the callback as the change token is one time use only and a new change token
|
||||||
// is produced every time
|
// is produced every time
|
||||||
Extensions.Primitives.ChangeToken.OnChange(
|
Extensions.Primitives.ChangeToken.OnChange(
|
||||||
() => _endpointDataSource.ChangeToken,
|
_endpointDataSource.GetChangeToken,
|
||||||
() => HandleChange());
|
HandleChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildOutboundMatches()
|
private void BuildOutboundMatches()
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,20 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
{
|
{
|
||||||
public class DispatcherTest : IDisposable
|
public class GlobalRoutingBenchmarkTest : IDisposable
|
||||||
{
|
{
|
||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
private readonly TestServer _testServer;
|
private readonly TestServer _testServer;
|
||||||
|
|
||||||
public DispatcherTest()
|
public GlobalRoutingBenchmarkTest()
|
||||||
{
|
{
|
||||||
// This switch and value are set by benchmark server when running the app for profiling.
|
// This switch and value are set by benchmark server when running the app for profiling.
|
||||||
var args = new[] { "--scenarios", "PlaintextDispatcher" };
|
var args = new[] { "--scenarios", "PlaintextGlobalRouting" };
|
||||||
var webHostBuilder = Benchmarks.Program.GetWebHostBuilder(args);
|
var webHostBuilder = Benchmarks.Program.GetWebHostBuilder(args);
|
||||||
|
|
||||||
// Make sure we are using the right startup
|
// Make sure we are using the right startup
|
||||||
var startupName = webHostBuilder.GetSetting("Startup");
|
var startupName = webHostBuilder.GetSetting("Startup");
|
||||||
Assert.Equal(nameof(Benchmarks.StartupUsingDispatcher), startupName);
|
Assert.Equal(nameof(Benchmarks.StartupUsingGlobalRouting), startupName);
|
||||||
|
|
||||||
_testServer = new TestServer(webHostBuilder);
|
_testServer = new TestServer(webHostBuilder);
|
||||||
_client = _testServer.CreateClient();
|
_client = _testServer.CreateClient();
|
||||||
|
|
@ -11,12 +11,12 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
{
|
{
|
||||||
public class RoutingTest : IDisposable
|
public class RouterBenchmarkTest : IDisposable
|
||||||
{
|
{
|
||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
private readonly TestServer _testServer;
|
private readonly TestServer _testServer;
|
||||||
|
|
||||||
public RoutingTest()
|
public RouterBenchmarkTest()
|
||||||
{
|
{
|
||||||
// This switch and value are set by benchmark server when running the app for profiling.
|
// This switch and value are set by benchmark server when running the app for profiling.
|
||||||
var args = new[] { "--scenarios", "PlaintextRouting" };
|
var args = new[] { "--scenarios", "PlaintextRouting" };
|
||||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
|
|
||||||
// Make sure we are using the right startup
|
// Make sure we are using the right startup
|
||||||
var startupName = webHostBuilder.GetSetting("Startup");
|
var startupName = webHostBuilder.GetSetting("Startup");
|
||||||
Assert.Equal(nameof(Benchmarks.StartupUsingRouting), startupName);
|
Assert.Equal(nameof(Benchmarks.StartupUsingRouter), startupName);
|
||||||
|
|
||||||
_testServer = new TestServer(webHostBuilder);
|
_testServer = new TestServer(webHostBuilder);
|
||||||
_client = _testServer.CreateClient();
|
_client = _testServer.CreateClient();
|
||||||
|
|
@ -6,18 +6,19 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
|
using RoutingSample.Web;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
{
|
{
|
||||||
public class DispatcherSampleTest : IDisposable
|
public class GlobalRoutingSampleTest : IDisposable
|
||||||
{
|
{
|
||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
private readonly TestServer _testServer;
|
private readonly TestServer _testServer;
|
||||||
|
|
||||||
public DispatcherSampleTest()
|
public GlobalRoutingSampleTest()
|
||||||
{
|
{
|
||||||
var webHostBuilder = DispatcherSample.Web.Program.GetWebHostBuilder();
|
var webHostBuilder = Program.GetWebHostBuilder(new[] { Program.GlobalRoutingScenario, });
|
||||||
_testServer = new TestServer(webHostBuilder);
|
_testServer = new TestServer(webHostBuilder);
|
||||||
_client = _testServer.CreateClient();
|
_client = _testServer.CreateClient();
|
||||||
_client.BaseAddress = new Uri("http://localhost");
|
_client.BaseAddress = new Uri("http://localhost");
|
||||||
|
|
@ -28,7 +29,7 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expectedContentType = "text/plain";
|
var expectedContentType = "text/plain";
|
||||||
var expectedContent = "Dispatcher sample endpoints:" + Environment.NewLine + "/plaintext";
|
var expectedContent = "Global Routing sample endpoints:" + Environment.NewLine + "/plaintext";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await _client.GetAsync("/");
|
var response = await _client.GetAsync("/");
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
|
||||||
<ProjectReference Include="..\..\samples\RoutingSample.Web\RoutingSample.Web.csproj" />
|
<ProjectReference Include="..\..\samples\RoutingSample.Web\RoutingSample.Web.csproj" />
|
||||||
<ProjectReference Include="..\..\samples\DispatcherSample.Web\DispatcherSample.Web.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,19 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
|
using RoutingSample.Web;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||||
{
|
{
|
||||||
public class RoutingSampleTest : IDisposable
|
public class RouterSampleTest : IDisposable
|
||||||
{
|
{
|
||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
private readonly TestServer _testServer;
|
private readonly TestServer _testServer;
|
||||||
|
|
||||||
public RoutingSampleTest()
|
public RouterSampleTest()
|
||||||
{
|
{
|
||||||
var webHostBuilder = RoutingSample.Web.Program.GetWebHostBuilder();
|
var webHostBuilder = Program.GetWebHostBuilder(new[] { Program.RouterScenario, });
|
||||||
_testServer = new TestServer(webHostBuilder);
|
_testServer = new TestServer(webHostBuilder);
|
||||||
_client = _testServer.CreateClient();
|
_client = _testServer.CreateClient();
|
||||||
_client.BaseAddress = new Uri("http://localhost");
|
_client.BaseAddress = new Uri("http://localhost");
|
||||||
|
|
@ -12,21 +12,21 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
namespace Microsoft.AspNetCore.Builder
|
||||||
{
|
{
|
||||||
public class DispatcherApplicationBuilderExtensionsTest
|
public class GlobalRoutingBuilderExtensionsTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void UseDispatcher_ServicesNotRegistered_Throws()
|
public void UseGlobalRouting_ServicesNotRegistered_Throws()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var app = new ApplicationBuilder(Mock.Of<IServiceProvider>());
|
var app = new ApplicationBuilder(Mock.Of<IServiceProvider>());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseDispatcher());
|
var ex = Assert.Throws<InvalidOperationException>(() => app.UseGlobalRouting());
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"Unable to find the required services. " +
|
"Unable to find the required services. " +
|
||||||
"Please add all the required services by calling 'IServiceCollection.AddDispatcher' " +
|
"Please add all the required services by calling 'IServiceCollection.AddRouting' " +
|
||||||
"inside the call to 'ConfigureServices(...)' in the application startup code.",
|
"inside the call to 'ConfigureServices(...)' in the application startup code.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
}
|
}
|
||||||
|
|
@ -43,20 +43,20 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"Unable to find the required services. " +
|
"Unable to find the required services. " +
|
||||||
"Please add all the required services by calling 'IServiceCollection.AddDispatcher' " +
|
"Please add all the required services by calling 'IServiceCollection.AddRouting' " +
|
||||||
"inside the call to 'ConfigureServices(...)' in the application startup code.",
|
"inside the call to 'ConfigureServices(...)' in the application startup code.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task UseDispatcher_ServicesRegistered_SetsFeature()
|
public async Task UseGlobalRouting_ServicesRegistered_SetsFeature()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var services = CreateServices();
|
var services = CreateServices();
|
||||||
|
|
||||||
var app = new ApplicationBuilder(services);
|
var app = new ApplicationBuilder(services);
|
||||||
|
|
||||||
app.UseDispatcher();
|
app.UseGlobalRouting();
|
||||||
|
|
||||||
var appFunc = app.Build();
|
var appFunc = app.Build();
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void UseEndpoint_ServicesRegisteredAndNoDispatcherRegistered_Throws()
|
public void UseEndpoint_WithoutRoutingServicesRegistered_Throws()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var services = CreateServices();
|
var services = CreateServices();
|
||||||
|
|
@ -81,21 +81,21 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"DispatcherMiddleware must be added to the request execution pipeline before EndpointMiddleware. " +
|
"GlobalRoutingMiddleware must be added to the request execution pipeline before EndpointMiddleware. " +
|
||||||
"Please add DispatcherMiddleware by calling 'IApplicationBuilder.UseDispatcher' " +
|
"Please add GlobalRoutingMiddleware by calling 'IApplicationBuilder.UseGlobalRouting' " +
|
||||||
"inside the call to 'Configure(...)' in the application startup code.",
|
"inside the call to 'Configure(...)' in the application startup code.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task UseEndpoint_ServicesRegisteredAndDispatcherRegistered_SetsFeature()
|
public async Task UseEndpoint_ServicesRegisteredAndGlobalRoutingRegistered_SetsFeature()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var services = CreateServices();
|
var services = CreateServices();
|
||||||
|
|
||||||
var app = new ApplicationBuilder(services);
|
var app = new ApplicationBuilder(services);
|
||||||
|
|
||||||
app.UseDispatcher();
|
app.UseGlobalRouting();
|
||||||
app.UseEndpoint();
|
app.UseEndpoint();
|
||||||
|
|
||||||
var appFunc = app.Build();
|
var appFunc = app.Build();
|
||||||
|
|
@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
|
|
||||||
services.AddLogging();
|
services.AddLogging();
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
services.AddDispatcher();
|
services.AddRouting();
|
||||||
|
|
||||||
return services.BuildServiceProvider();
|
return services.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|
@ -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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -14,6 +14,28 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
{
|
{
|
||||||
public class RoutingBuilderExtensionsTest
|
public class RoutingBuilderExtensionsTest
|
||||||
{
|
{
|
||||||
|
[Fact]
|
||||||
|
public void UseRouter_ThrowsInvalidOperationException_IfRoutingMarkerServiceIsNotRegistered()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var applicationBuilderMock = new Mock<IApplicationBuilder>();
|
||||||
|
applicationBuilderMock
|
||||||
|
.Setup(s => s.ApplicationServices)
|
||||||
|
.Returns(Mock.Of<IServiceProvider>());
|
||||||
|
|
||||||
|
var router = Mock.Of<IRouter>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(
|
||||||
|
() => applicationBuilderMock.Object.UseRouter(router));
|
||||||
|
|
||||||
|
Assert.Equal(
|
||||||
|
"Unable to find the required services. Please add all the required services by calling " +
|
||||||
|
"'IServiceCollection.AddRouting' inside the call to 'ConfigureServices(...)'" +
|
||||||
|
" in the application startup code.",
|
||||||
|
exception.Message);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void UseRouter_IRouter_ThrowsWithoutCallingAddRouting()
|
public void UseRouter_IRouter_ThrowsWithoutCallingAddRouting()
|
||||||
{
|
{
|
||||||
|
|
@ -59,7 +81,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
var router = new Mock<IRouter>(MockBehavior.Strict);
|
var router = new Mock<IRouter>(MockBehavior.Strict);
|
||||||
router
|
router
|
||||||
.Setup(r => r.RouteAsync(It.IsAny<RouteContext>()))
|
.Setup(r => r.RouteAsync(It.IsAny<RouteContext>()))
|
||||||
.Returns(Task.FromResult(0))
|
.Returns(Task.CompletedTask)
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
|
|
||||||
app.UseRouter(router.Object);
|
app.UseRouter(router.Object);
|
||||||
|
|
@ -84,7 +106,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
var router = new Mock<IRouter>(MockBehavior.Strict);
|
var router = new Mock<IRouter>(MockBehavior.Strict);
|
||||||
router
|
router
|
||||||
.Setup(r => r.RouteAsync(It.IsAny<RouteContext>()))
|
.Setup(r => r.RouteAsync(It.IsAny<RouteContext>()))
|
||||||
.Returns(Task.FromResult(0))
|
.Returns(Task.CompletedTask)
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
|
|
||||||
app.UseRouter(b =>
|
app.UseRouter(b =>
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
// 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;
|
|
||||||
using Microsoft.AspNetCore.Routing;
|
|
||||||
using Moq;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
|
||||||
{
|
|
||||||
public class BuilderExtensionsTest
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void UseRouter_ThrowsInvalidOperationException_IfRoutingMarkerServiceIsNotRegistered()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var applicationBuilderMock = new Mock<IApplicationBuilder>();
|
|
||||||
applicationBuilderMock
|
|
||||||
.Setup(s => s.ApplicationServices)
|
|
||||||
.Returns(Mock.Of<IServiceProvider>());
|
|
||||||
|
|
||||||
var router = Mock.Of<IRouter>();
|
|
||||||
|
|
||||||
// Act & Assert
|
|
||||||
var exception = Assert.Throws<InvalidOperationException>(
|
|
||||||
() => applicationBuilderMock.Object.UseRouter(router));
|
|
||||||
|
|
||||||
Assert.Equal(
|
|
||||||
"Unable to find the required services. Please add all the required services by calling " +
|
|
||||||
"'IServiceCollection.AddRouting' inside the call to 'ConfigureServices(...)'" +
|
|
||||||
" in the application startup code.",
|
|
||||||
exception.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var endpoints = compositeDataSource.Endpoints;
|
var endpoints = compositeDataSource.Endpoints;
|
||||||
|
|
||||||
// Assert1
|
// Assert1
|
||||||
var changeToken1 = compositeDataSource.ChangeToken;
|
var changeToken1 = compositeDataSource.GetChangeToken();
|
||||||
var token = Assert.IsType<CancellationChangeToken>(changeToken1);
|
var token = Assert.IsType<CancellationChangeToken>(changeToken1);
|
||||||
Assert.False(token.HasChanged); // initial state
|
Assert.False(token.HasChanged); // initial state
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
// Assert2
|
// Assert2
|
||||||
Assert.True(changeToken1.HasChanged); // old token is expected to be changed
|
Assert.True(changeToken1.HasChanged); // old token is expected to be changed
|
||||||
var changeToken2 = compositeDataSource.ChangeToken; // new token is in a unchanged state
|
var changeToken2 = compositeDataSource.GetChangeToken(); // new token is in a unchanged state
|
||||||
Assert.NotSame(changeToken2, changeToken1);
|
Assert.NotSame(changeToken2, changeToken1);
|
||||||
token = Assert.IsType<CancellationChangeToken>(changeToken2);
|
token = Assert.IsType<CancellationChangeToken>(changeToken2);
|
||||||
Assert.False(token.HasChanged);
|
Assert.False(token.HasChanged);
|
||||||
|
|
@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
// Assert2
|
// Assert2
|
||||||
Assert.True(changeToken2.HasChanged); // old token is expected to be changed
|
Assert.True(changeToken2.HasChanged); // old token is expected to be changed
|
||||||
var changeToken3 = compositeDataSource.ChangeToken; // new token is in a unchanged state
|
var changeToken3 = compositeDataSource.GetChangeToken(); // new token is in a unchanged state
|
||||||
Assert.NotSame(changeToken3, changeToken2);
|
Assert.NotSame(changeToken3, changeToken2);
|
||||||
Assert.NotSame(changeToken3, changeToken1);
|
Assert.NotSame(changeToken3, changeToken1);
|
||||||
token = Assert.IsType<CancellationChangeToken>(changeToken3);
|
token = Assert.IsType<CancellationChangeToken>(changeToken3);
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,9 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await invokeTask);
|
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await invokeTask);
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"Unable to execute an endpoint because the DispatcherMiddleware was not run for this request. " +
|
"Unable to execute an endpoint because the GlobalRoutingMiddleware was not run for this request. " +
|
||||||
"Ensure DispatcherMiddleware is added to the request execution pipeline before EndpointMiddleware in application startup code.",
|
"Ensure GlobalRoutingMiddleware is added to the request execution pipeline before EndpointMiddleware " +
|
||||||
|
"in application startup code.",
|
||||||
ex.Message);
|
ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
public class DispatcherMiddlewareTest
|
public class GlobalRoutingMiddlewareTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Invoke_OnCall_SetsEndpointFeature()
|
public async Task Invoke_OnCall_SetsEndpointFeature()
|
||||||
|
|
@ -39,14 +39,14 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var expectedMessage = "Request matched endpoint 'Test endpoint'.";
|
var expectedMessage = "Request matched endpoint 'Test endpoint'.";
|
||||||
|
|
||||||
var sink = new TestSink(
|
var sink = new TestSink(
|
||||||
TestSink.EnableWithTypeName<DispatcherMiddleware>,
|
TestSink.EnableWithTypeName<GlobalRoutingMiddleware>,
|
||||||
TestSink.EnableWithTypeName<DispatcherMiddleware>);
|
TestSink.EnableWithTypeName<GlobalRoutingMiddleware>);
|
||||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||||
|
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
httpContext.RequestServices = new TestServiceProvider();
|
httpContext.RequestServices = new TestServiceProvider();
|
||||||
|
|
||||||
var logger = new Logger<DispatcherMiddleware>(loggerFactory);
|
var logger = new Logger<GlobalRoutingMiddleware>(loggerFactory);
|
||||||
var middleware = CreateMiddleware(logger);
|
var middleware = CreateMiddleware(logger);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -82,15 +82,15 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
Assert.Equal("testValue", endpointFeature.Values["testKey"]);
|
Assert.Equal("testValue", endpointFeature.Values["testKey"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DispatcherMiddleware CreateMiddleware(Logger<DispatcherMiddleware> logger = null)
|
private GlobalRoutingMiddleware CreateMiddleware(Logger<GlobalRoutingMiddleware> logger = null)
|
||||||
{
|
{
|
||||||
RequestDelegate next = (c) => Task.FromResult<object>(null);
|
RequestDelegate next = (c) => Task.FromResult<object>(null);
|
||||||
|
|
||||||
logger = logger ?? new Logger<DispatcherMiddleware>(NullLoggerFactory.Instance);
|
logger = logger ?? new Logger<GlobalRoutingMiddleware>(NullLoggerFactory.Instance);
|
||||||
|
|
||||||
var options = Options.Create(new DispatcherOptions());
|
var options = Options.Create(new EndpointOptions());
|
||||||
var matcherFactory = new TestMatcherFactory(true);
|
var matcherFactory = new TestMatcherFactory(true);
|
||||||
var middleware = new DispatcherMiddleware(
|
var middleware = new GlobalRoutingMiddleware(
|
||||||
matcherFactory,
|
matcherFactory,
|
||||||
new CompositeEndpointDataSource(Array.Empty<EndpointDataSource>()),
|
new CompositeEndpointDataSource(Array.Empty<EndpointDataSource>()),
|
||||||
logger,
|
logger,
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override Matcher CreateMatcher(params MatcherEndpoint[] endpoints)
|
internal override Matcher CreateMatcher(params MatcherEndpoint[] endpoints)
|
||||||
|
|
@ -29,7 +29,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
.AddLogging()
|
.AddLogging()
|
||||||
.AddOptions()
|
.AddOptions()
|
||||||
.AddRouting()
|
.AddRouting()
|
||||||
.AddDispatcher()
|
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
var builder = services.GetRequiredService<DfaMatcherBuilder>();
|
var builder = services.GetRequiredService<DfaMatcherBuilder>();
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
.AddLogging()
|
.AddLogging()
|
||||||
.AddOptions()
|
.AddOptions()
|
||||||
.AddRouting()
|
.AddRouting()
|
||||||
.AddDispatcher()
|
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
var factory = services.GetRequiredService<MatcherFactory>();
|
var factory = services.GetRequiredService<MatcherFactory>();
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", });
|
MatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", d = "19" });
|
MatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", d = "19" });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -168,7 +168,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Historically catchall segments don't match an empty segment, but only if it's
|
// Historically catchall segments don't match an empty segment, but only if it's
|
||||||
|
|
@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
|
|
||||||
// Need to access these to prevent a warning from the xUnit analyzer.
|
// Need to access these to prevent a warning from the xUnit analyzer.
|
||||||
// Some of these tests will match (and process the values) and some will not.
|
// Some of these tests will match (and process the values) and some will not.
|
||||||
|
|
@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -272,7 +272,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -298,7 +298,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Most of are copied from old routing tests that date back to the VS 2010 era. Enjoy!
|
// Most of are copied from old routing tests that date back to the VS 2010 era. Enjoy!
|
||||||
|
|
@ -323,7 +323,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -353,7 +353,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
MatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -387,7 +387,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
MatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -440,7 +440,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
MatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using Xunit.Sdk;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing.Matchers
|
namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
{
|
{
|
||||||
internal static class DispatcherAssert
|
internal static class MatcherAssert
|
||||||
{
|
{
|
||||||
public static void AssertMatch(IEndpointFeature feature, Endpoint expected)
|
public static void AssertMatch(IEndpointFeature feature, Endpoint expected)
|
||||||
{
|
{
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some matchers will optimize for the ASCII case
|
// Some matchers will optimize for the ASCII case
|
||||||
|
|
@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matchers should operate on the decoded representation - a matcher that calls
|
// Matchers should operate on the decoded representation - a matcher that calls
|
||||||
|
|
@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matchers do their own 'splitting' of the path into segments, so including
|
// Matchers do their own 'splitting' of the path into segments, so including
|
||||||
|
|
@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
MatcherAssert.AssertMatch(feature, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matchers do their own 'splitting' of the path into segments, so including
|
// Matchers do their own 'splitting' of the path into segments, so including
|
||||||
|
|
@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -205,7 +205,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -273,7 +273,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -323,7 +323,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
||||||
await matcher.MatchAsync(httpContext, feature);
|
await matcher.MatchAsync(httpContext, feature);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
DispatcherAssert.AssertNotMatch(feature);
|
MatcherAssert.AssertNotMatch(feature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
// add routes that behave as advertised.
|
// add routes that behave as advertised.
|
||||||
public class RequestDelegateRouteBuilderExtensionsTest
|
public class RequestDelegateRouteBuilderExtensionsTest
|
||||||
{
|
{
|
||||||
private static readonly RequestDelegate NullHandler = (c) => Task.FromResult(0);
|
private static readonly RequestDelegate NullHandler = (c) => Task.CompletedTask;
|
||||||
|
|
||||||
public static TheoryData<Action<IRouteBuilder>, Action<HttpContext>> MatchingActions
|
public static TheoryData<Action<IRouteBuilder>, Action<HttpContext>> MatchingActions
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
public class RouteCollectionTest
|
public class RouteCollectionTest
|
||||||
{
|
{
|
||||||
private static readonly RequestDelegate NullHandler = (c) => Task.FromResult(0);
|
private static readonly RequestDelegate NullHandler = (c) => Task.CompletedTask;
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(@"Home/Index/23", "/home/index/23", true, false)]
|
[InlineData(@"Home/Index/23", "/home/index/23", true, false)]
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
public class RouteTest
|
public class RouteTest
|
||||||
{
|
{
|
||||||
private static readonly RequestDelegate NullHandler = (c) => Task.FromResult(0);
|
private static readonly RequestDelegate NullHandler = (c) => Task.CompletedTask;
|
||||||
private static IInlineConstraintResolver _inlineConstraintResolver = GetInlineConstraintResolver();
|
private static IInlineConstraintResolver _inlineConstraintResolver = GetInlineConstraintResolver();
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
|
|
||||||
public Task RouteAsync(RouteContext context)
|
public Task RouteAsync(RouteContext context)
|
||||||
{
|
{
|
||||||
context.Handler = _isHandled ? (RequestDelegate)((c) => Task.FromResult(0)) : null;
|
context.Handler = _isHandled ? (RequestDelegate)((c) => Task.CompletedTask) : null;
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
{
|
{
|
||||||
public class TreeRouterTest
|
public class TreeRouterTest
|
||||||
{
|
{
|
||||||
private static readonly RequestDelegate NullHandler = (c) => Task.FromResult(0);
|
private static readonly RequestDelegate NullHandler = (c) => Task.CompletedTask;
|
||||||
|
|
||||||
private static ObjectPool<UriBuildingContext> Pool = new DefaultObjectPoolProvider().Create(
|
private static ObjectPool<UriBuildingContext> Pool = new DefaultObjectPoolProvider().Create(
|
||||||
new UriBuilderContextPooledObjectPolicy());
|
new UriBuilderContextPooledObjectPolicy());
|
||||||
|
|
@ -1820,7 +1820,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
||||||
c.Handler = null; // Not a match
|
c.Handler = null; // Not a match
|
||||||
})
|
})
|
||||||
.Returns(Task.FromResult(0));
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var builder = CreateBuilder();
|
var builder = CreateBuilder();
|
||||||
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
||||||
|
|
@ -1857,7 +1857,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
||||||
c.Handler = null; // Not a match
|
c.Handler = null; // Not a match
|
||||||
})
|
})
|
||||||
.Returns(Task.FromResult(0));
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var builder = CreateBuilder();
|
var builder = CreateBuilder();
|
||||||
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
||||||
|
|
@ -1901,7 +1901,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
})
|
})
|
||||||
.Returns(Task.FromResult(0));
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var builder = CreateBuilder();
|
var builder = CreateBuilder();
|
||||||
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue