Change Branding
For preview one the branding is: new thing = UseGlobalRouting/UseEndpoint old thing = UseRouter We're going to drop the name Dispatcher everywhere and make sure that we position our new work as 'new and improved routing' instead of introducing a new product/concept name. We're not totally sure of the term Global yet, but it's what we're doing for preview 1. Suggestions welcome for dicussion after we do the first preview :)
This commit is contained in:
parent
c89c2c643b
commit
b9df95831d
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
|
||||
VisualStudioVersion = 15.0.27106.3000
|
||||
MinimumVisualStudioVersion = 15.0.26730.03
|
||||
|
|
@ -44,15 +45,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6DC6B416
|
|||
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}"
|
||||
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}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarkapps", "benchmarkapps", "{7F5914E2-C63F-4759-898E-462804357C90}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "benchmarkapps\Benchmarks\Benchmarks.csproj", "{91F47A60-9A78-4968-B10D-157D9BFAC37F}"
|
||||
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
|
||||
Global
|
||||
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|x86.ActiveCfg = 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.Build.0 = 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}
|
||||
{5C73140B-41F3-466F-A07B-3614E4D80DF9} = {95359B4B-4C85-4B44-A75B-0621905C4CF6}
|
||||
{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}
|
||||
{990ECDEE-49DE-45E3-B0D9-DDEB9CFF6A9D} = {D5F39F59-5725-4127-82E7-67028D006185}
|
||||
EndGlobalSection
|
||||
|
|
|
|||
|
|
@ -29,22 +29,22 @@ namespace Benchmarks
|
|||
.UseKestrel();
|
||||
|
||||
var scenario = config["scenarios"]?.ToLower();
|
||||
if (scenario == "plaintextdispatcher")
|
||||
if (scenario == "plaintextdispatcher" || scenario == "plaintextglobalrouting")
|
||||
{
|
||||
webHostBuilder.UseStartup<StartupUsingDispatcher>();
|
||||
webHostBuilder.UseStartup<StartupUsingGlobalRouting>();
|
||||
// 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
|
||||
webHostBuilder.UseSetting("Startup", nameof(StartupUsingRouting));
|
||||
webHostBuilder.UseSetting("Startup", nameof(StartupUsingRouter));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Invalid scenario '{scenario}'. Allowed scenarios are PlaintextDispatcher and PlaintextRouting");
|
||||
$"Invalid scenario '{scenario}'. Allowed scenarios are PlaintextGlobalRouting and PlaintextRouter");
|
||||
}
|
||||
|
||||
return webHostBuilder;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace Benchmarks
|
||||
{
|
||||
public class StartupUsingDispatcher
|
||||
public class StartupUsingGlobalRouting
|
||||
{
|
||||
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ namespace Benchmarks
|
|||
{
|
||||
services.AddRouting();
|
||||
|
||||
services.AddDispatcher(options =>
|
||||
services.Configure<EndpointOptions>(options =>
|
||||
{
|
||||
options.DataSources.Add(new DefaultEndpointDataSource(new[]
|
||||
{
|
||||
|
|
@ -43,7 +43,7 @@ namespace Benchmarks
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDispatcher();
|
||||
app.UseGlobalRouting();
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ using System.Text;
|
|||
|
||||
namespace Benchmarks
|
||||
{
|
||||
public class StartupUsingRouting
|
||||
public class StartupUsingRouter
|
||||
{
|
||||
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
|
||||
|
||||
|
|
@ -16,7 +16,13 @@
|
|||
"PlaintextRouting": {
|
||||
"Path": "/plaintext"
|
||||
},
|
||||
"PlaintextRouter": {
|
||||
"Path": "/plaintext"
|
||||
},
|
||||
"PlaintextDispatcher": {
|
||||
"Path": "/plaintext"
|
||||
},
|
||||
"PlaintextGlobalRouting": {
|
||||
"Path": "/plaintext"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
var sample = _samples[i];
|
||||
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);
|
||||
|
||||
await _tree.MatchAsync(httpContext, feature);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
services.AddLogging();
|
||||
services.AddOptions();
|
||||
services.AddRouting();
|
||||
services.AddDispatcher();
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
{
|
||||
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);
|
||||
|
||||
await _tree.MatchAsync(httpContext, feature);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
|
||||
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);
|
||||
|
||||
await _tree.MatchAsync(httpContext, feature);
|
||||
|
|
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
var feature = _feature;
|
||||
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);
|
||||
|
||||
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.Extensions.Logging;
|
||||
|
||||
namespace DispatcherSample.Web
|
||||
namespace RoutingSample.Web
|
||||
{
|
||||
internal class EndsWithStringMatchProcessor : MatchProcessorBase
|
||||
{
|
||||
|
|
@ -44,14 +44,14 @@ namespace RoutingSample.Web
|
|||
var lastCharacter = requestPath[_prefix.Length];
|
||||
if (lastCharacter != '/' && lastCharacter != '#' && lastCharacter != '?')
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
context.Handler = _target.GetRequestHandler(context.HttpContext, context.RouteData);
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public VirtualPathData GetVirtualPath(VirtualPathContext context)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
|
|
@ -8,19 +9,57 @@ namespace RoutingSample.Web
|
|||
{
|
||||
public class Program
|
||||
{
|
||||
public static readonly string GlobalRoutingScenario = "globalrouting";
|
||||
public static readonly string RouterScenario = "router";
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var webHost = GetWebHostBuilder().Build();
|
||||
var webHost = GetWebHostBuilder(args).Build();
|
||||
webHost.Run();
|
||||
}
|
||||
|
||||
// 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()
|
||||
.UseKestrel()
|
||||
.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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
|
@ -11,11 +10,11 @@ using Microsoft.AspNetCore.Routing.Matchers;
|
|||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
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!");
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
|
|
@ -26,11 +25,11 @@ namespace DispatcherSample.Web
|
|||
{
|
||||
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) =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
|
|
@ -83,13 +82,13 @@ namespace DispatcherSample.Web
|
|||
0,
|
||||
EndpointMetadataCollection.Empty,
|
||||
"withoptionalconstraints"),
|
||||
}));
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDispatcher();
|
||||
app.UseGlobalRouting();
|
||||
|
||||
// Imagine some more stuff here...
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace RoutingSample.Web
|
||||
{
|
||||
public class Startup
|
||||
public class UseRouterStartup
|
||||
{
|
||||
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(...)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,11 +8,11 @@ using Microsoft.Extensions.Options;
|
|||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
internal class ConfigureDispatcherOptions : IConfigureOptions<DispatcherOptions>
|
||||
internal class ConfigureEndpointOptions : IConfigureOptions<EndpointOptions>
|
||||
{
|
||||
private readonly IEnumerable<EndpointDataSource> _dataSources;
|
||||
|
||||
public ConfigureDispatcherOptions(IEnumerable<EndpointDataSource> dataSources)
|
||||
public ConfigureEndpointOptions(IEnumerable<EndpointDataSource> dataSources)
|
||||
{
|
||||
if (dataSources == null)
|
||||
{
|
||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
_dataSources = dataSources;
|
||||
}
|
||||
|
||||
public void Configure(DispatcherOptions options)
|
||||
public void Configure(EndpointOptions options)
|
||||
{
|
||||
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.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
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
|
||||
{
|
||||
// This whole class is temporary until we can remove its usage from MVC
|
||||
public static class DispatcherServiceCollectionExtensions
|
||||
{
|
||||
// This whole class is temporary until we can remove its usage from MVC
|
||||
public static IServiceCollection AddDispatcher(this IServiceCollection services)
|
||||
{
|
||||
if (services == null)
|
||||
|
|
@ -22,53 +17,21 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
// Collect all data sources from DI.
|
||||
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;
|
||||
return services.AddRouting();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
services.AddDispatcher();
|
||||
services.AddRouting();
|
||||
if (configuration != null)
|
||||
{
|
||||
services.Configure<DispatcherOptions>(configuration);
|
||||
services.Configure<EndpointOptions>(configuration);
|
||||
}
|
||||
|
||||
return services;
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
using System;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Constraints;
|
||||
using Microsoft.AspNetCore.Routing.EndpointConstraints;
|
||||
using Microsoft.AspNetCore.Routing.EndpointFinders;
|
||||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using Microsoft.AspNetCore.Routing.Matchers;
|
||||
using Microsoft.AspNetCore.Routing.Tree;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
|
|
@ -49,6 +52,37 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.Routing
|
|||
var feature = httpContext.Features.Get<IEndpointFeature>();
|
||||
if (feature == null)
|
||||
{
|
||||
var message = $"Unable to execute an endpoint because the {nameof(DispatcherMiddleware)} was not run for this request. " +
|
||||
$"Ensure {nameof(DispatcherMiddleware)} is added to the request execution pipeline before {nameof(EndpointMiddleware)} in application startup code.";
|
||||
var message = $"Unable to execute an endpoint because the {nameof(GlobalRoutingMiddleware)} was not run for this request. " +
|
||||
$"Ensure {nameof(GlobalRoutingMiddleware)} is added to the request execution pipeline before {nameof(EndpointMiddleware)} in application startup code.";
|
||||
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public class DispatcherOptions
|
||||
public class EndpointOptions
|
||||
{
|
||||
public IList<EndpointDataSource> DataSources { get; } = new List<EndpointDataSource>();
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ using Microsoft.Extensions.Options;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
internal sealed class DispatcherMiddleware
|
||||
internal sealed class GlobalRoutingMiddleware
|
||||
{
|
||||
private readonly MatcherFactory _matcherFactory;
|
||||
private readonly ILogger _logger;
|
||||
|
|
@ -20,10 +20,10 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
private Task<Matcher> _initializationTask;
|
||||
|
||||
public DispatcherMiddleware(
|
||||
public GlobalRoutingMiddleware(
|
||||
MatcherFactory matcherFactory,
|
||||
CompositeEndpointDataSource endpointDataSource,
|
||||
ILogger<DispatcherMiddleware> logger,
|
||||
ILogger<GlobalRoutingMiddleware> logger,
|
||||
RequestDelegate next)
|
||||
{
|
||||
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>
|
||||
/// 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>
|
||||
internal abstract class Matcher
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,20 +11,20 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||
{
|
||||
public class DispatcherTest : IDisposable
|
||||
public class GlobalRoutingBenchmarkTest : IDisposable
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
private readonly TestServer _testServer;
|
||||
|
||||
public DispatcherTest()
|
||||
public GlobalRoutingBenchmarkTest()
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Make sure we are using the right startup
|
||||
var startupName = webHostBuilder.GetSetting("Startup");
|
||||
Assert.Equal(nameof(Benchmarks.StartupUsingDispatcher), startupName);
|
||||
Assert.Equal(nameof(Benchmarks.StartupUsingGlobalRouting), startupName);
|
||||
|
||||
_testServer = new TestServer(webHostBuilder);
|
||||
_client = _testServer.CreateClient();
|
||||
|
|
@ -11,12 +11,12 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||
{
|
||||
public class RoutingTest : IDisposable
|
||||
public class RouterBenchmarkTest : IDisposable
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
private readonly TestServer _testServer;
|
||||
|
||||
public RoutingTest()
|
||||
public RouterBenchmarkTest()
|
||||
{
|
||||
// This switch and value are set by benchmark server when running the app for profiling.
|
||||
var args = new[] { "--scenarios", "PlaintextRouting" };
|
||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
|||
|
||||
// Make sure we are using the right startup
|
||||
var startupName = webHostBuilder.GetSetting("Startup");
|
||||
Assert.Equal(nameof(Benchmarks.StartupUsingRouting), startupName);
|
||||
Assert.Equal(nameof(Benchmarks.StartupUsingRouter), startupName);
|
||||
|
||||
_testServer = new TestServer(webHostBuilder);
|
||||
_client = _testServer.CreateClient();
|
||||
|
|
@ -6,18 +6,19 @@ using System.Net;
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using RoutingSample.Web;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||
{
|
||||
public class DispatcherSampleTest : IDisposable
|
||||
public class GlobalRoutingSampleTest : IDisposable
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
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);
|
||||
_client = _testServer.CreateClient();
|
||||
_client.BaseAddress = new Uri("http://localhost");
|
||||
|
|
@ -28,7 +29,7 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
|||
{
|
||||
// Arrange
|
||||
var expectedContentType = "text/plain";
|
||||
var expectedContent = "Dispatcher sample endpoints:" + Environment.NewLine + "/plaintext";
|
||||
var expectedContent = "Global Routing sample endpoints:" + Environment.NewLine + "/plaintext";
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync("/");
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
|
||||
<ProjectReference Include="..\..\samples\RoutingSample.Web\RoutingSample.Web.csproj" />
|
||||
<ProjectReference Include="..\..\samples\DispatcherSample.Web\DispatcherSample.Web.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -6,18 +6,19 @@ using System.Net;
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using RoutingSample.Web;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing.FunctionalTests
|
||||
{
|
||||
public class RoutingSampleTest : IDisposable
|
||||
public class RouterSampleTest : IDisposable
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
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);
|
||||
_client = _testServer.CreateClient();
|
||||
_client.BaseAddress = new Uri("http://localhost");
|
||||
|
|
@ -12,21 +12,21 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public class DispatcherApplicationBuilderExtensionsTest
|
||||
public class GlobalRoutingBuilderExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void UseDispatcher_ServicesNotRegistered_Throws()
|
||||
public void UseGlobalRouting_ServicesNotRegistered_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var app = new ApplicationBuilder(Mock.Of<IServiceProvider>());
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseDispatcher());
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseGlobalRouting());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
"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.",
|
||||
ex.Message);
|
||||
}
|
||||
|
|
@ -43,20 +43,20 @@ namespace Microsoft.AspNetCore.Builder
|
|||
// Assert
|
||||
Assert.Equal(
|
||||
"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.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UseDispatcher_ServicesRegistered_SetsFeature()
|
||||
public async Task UseGlobalRouting_ServicesRegistered_SetsFeature()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseDispatcher();
|
||||
app.UseGlobalRouting();
|
||||
|
||||
var appFunc = app.Build();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void UseEndpoint_ServicesRegisteredAndNoDispatcherRegistered_Throws()
|
||||
public void UseEndpoint_WithoutRoutingServicesRegistered_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
|
@ -81,21 +81,21 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
"DispatcherMiddleware must be added to the request execution pipeline before EndpointMiddleware. " +
|
||||
"Please add DispatcherMiddleware by calling 'IApplicationBuilder.UseDispatcher' " +
|
||||
"GlobalRoutingMiddleware must be added to the request execution pipeline before EndpointMiddleware. " +
|
||||
"Please add GlobalRoutingMiddleware by calling 'IApplicationBuilder.UseGlobalRouting' " +
|
||||
"inside the call to 'Configure(...)' in the application startup code.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UseEndpoint_ServicesRegisteredAndDispatcherRegistered_SetsFeature()
|
||||
public async Task UseEndpoint_ServicesRegisteredAndGlobalRoutingRegistered_SetsFeature()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseDispatcher();
|
||||
app.UseGlobalRouting();
|
||||
app.UseEndpoint();
|
||||
|
||||
var appFunc = app.Build();
|
||||
|
|
@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
services.AddLogging();
|
||||
services.AddOptions();
|
||||
services.AddDispatcher();
|
||||
services.AddRouting();
|
||||
|
||||
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.
|
||||
|
||||
using System;
|
||||
|
|
@ -14,6 +14,28 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
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]
|
||||
public void UseRouter_IRouter_ThrowsWithoutCallingAddRouting()
|
||||
{
|
||||
|
|
@ -59,7 +81,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
var router = new Mock<IRouter>(MockBehavior.Strict);
|
||||
router
|
||||
.Setup(r => r.RouteAsync(It.IsAny<RouteContext>()))
|
||||
.Returns(Task.FromResult(0))
|
||||
.Returns(Task.CompletedTask)
|
||||
.Verifiable();
|
||||
|
||||
app.UseRouter(router.Object);
|
||||
|
|
@ -84,7 +106,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
var router = new Mock<IRouter>(MockBehavior.Strict);
|
||||
router
|
||||
.Setup(r => r.RouteAsync(It.IsAny<RouteContext>()))
|
||||
.Returns(Task.FromResult(0))
|
||||
.Returns(Task.CompletedTask)
|
||||
.Verifiable();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,8 +35,9 @@ namespace Microsoft.AspNetCore.Routing
|
|||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await invokeTask);
|
||||
|
||||
Assert.Equal(
|
||||
"Unable to execute an endpoint because the DispatcherMiddleware was not run for this request. " +
|
||||
"Ensure DispatcherMiddleware is added to the request execution pipeline before EndpointMiddleware in application startup code.",
|
||||
"Unable to execute an endpoint because the GlobalRoutingMiddleware was not run for this request. " +
|
||||
"Ensure GlobalRoutingMiddleware is added to the request execution pipeline before EndpointMiddleware " +
|
||||
"in application startup code.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
public class DispatcherMiddlewareTest
|
||||
public class GlobalRoutingMiddlewareTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Invoke_OnCall_SetsEndpointFeature()
|
||||
|
|
@ -39,14 +39,14 @@ namespace Microsoft.AspNetCore.Routing
|
|||
var expectedMessage = "Request matched endpoint 'Test endpoint'.";
|
||||
|
||||
var sink = new TestSink(
|
||||
TestSink.EnableWithTypeName<DispatcherMiddleware>,
|
||||
TestSink.EnableWithTypeName<DispatcherMiddleware>);
|
||||
TestSink.EnableWithTypeName<GlobalRoutingMiddleware>,
|
||||
TestSink.EnableWithTypeName<GlobalRoutingMiddleware>);
|
||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.RequestServices = new TestServiceProvider();
|
||||
|
||||
var logger = new Logger<DispatcherMiddleware>(loggerFactory);
|
||||
var logger = new Logger<GlobalRoutingMiddleware>(loggerFactory);
|
||||
var middleware = CreateMiddleware(logger);
|
||||
|
||||
// Act
|
||||
|
|
@ -82,15 +82,15 @@ namespace Microsoft.AspNetCore.Routing
|
|||
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);
|
||||
|
||||
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 middleware = new DispatcherMiddleware(
|
||||
var middleware = new GlobalRoutingMiddleware(
|
||||
matcherFactory,
|
||||
new CompositeEndpointDataSource(Array.Empty<EndpointDataSource>()),
|
||||
logger,
|
||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
}
|
||||
|
||||
internal override Matcher CreateMatcher(params MatcherEndpoint[] endpoints)
|
||||
|
|
@ -29,7 +29,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
.AddLogging()
|
||||
.AddOptions()
|
||||
.AddRouting()
|
||||
.AddDispatcher()
|
||||
.BuildServiceProvider();
|
||||
|
||||
var builder = services.GetRequiredService<DfaMatcherBuilder>();
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
.AddLogging()
|
||||
.AddOptions()
|
||||
.AddRouting()
|
||||
.AddDispatcher()
|
||||
.BuildServiceProvider();
|
||||
|
||||
var factory = services.GetRequiredService<MatcherFactory>();
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", });
|
||||
MatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", d = "19" });
|
||||
MatcherAssert.AssertMatch(feature, endpoint, new { b = "17", c = "18", d = "19" });
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -168,7 +168,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// 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
|
||||
|
|
@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
|
||||
// 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.
|
||||
|
|
@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -272,7 +272,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -298,7 +298,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -353,7 +353,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
||||
MatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -387,7 +387,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
||||
MatcherAssert.AssertMatch(feature, expected, ignoreValues: true);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -440,7 +440,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// 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
|
||||
{
|
||||
internal static class DispatcherAssert
|
||||
internal static class MatcherAssert
|
||||
{
|
||||
public static void AssertMatch(IEndpointFeature feature, Endpoint expected)
|
||||
{
|
||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
// Some matchers will optimize for the ASCII case
|
||||
|
|
@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint);
|
||||
MatcherAssert.AssertMatch(feature, endpoint);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -205,7 +205,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, values);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -273,7 +273,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
MatcherAssert.AssertMatch(feature, endpoint, keys, values);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -323,7 +323,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
|
|||
await matcher.MatchAsync(httpContext, feature);
|
||||
|
||||
// Assert
|
||||
DispatcherAssert.AssertNotMatch(feature);
|
||||
MatcherAssert.AssertNotMatch(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
// add routes that behave as advertised.
|
||||
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
{
|
||||
public class RouteCollectionTest
|
||||
{
|
||||
private static readonly RequestDelegate NullHandler = (c) => Task.FromResult(0);
|
||||
private static readonly RequestDelegate NullHandler = (c) => Task.CompletedTask;
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"Home/Index/23", "/home/index/23", true, false)]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
{
|
||||
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();
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
|||
{
|
||||
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(
|
||||
new UriBuilderContextPooledObjectPolicy());
|
||||
|
|
@ -1820,7 +1820,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
|||
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
||||
c.Handler = null; // Not a match
|
||||
})
|
||||
.Returns(Task.FromResult(0));
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
var builder = CreateBuilder();
|
||||
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
||||
|
|
@ -1857,7 +1857,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
|||
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
||||
c.Handler = null; // Not a match
|
||||
})
|
||||
.Returns(Task.FromResult(0));
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
var builder = CreateBuilder();
|
||||
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
||||
|
|
@ -1901,7 +1901,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
|||
nestedRouters = new List<IRouter>(c.RouteData.Routers);
|
||||
throw new Exception();
|
||||
})
|
||||
.Returns(Task.FromResult(0));
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
var builder = CreateBuilder();
|
||||
MapInboundEntry(builder, "api/Store", handler: next.Object);
|
||||
|
|
|
|||
Loading…
Reference in New Issue