diff --git a/samples/DispatcherSample/Startup.cs b/samples/DispatcherSample/Startup.cs index 38314595bc..de78737032 100644 --- a/samples/DispatcherSample/Startup.cs +++ b/samples/DispatcherSample/Startup.cs @@ -1,9 +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.Collections.Generic; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Dispatcher; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; @@ -17,6 +15,7 @@ namespace DispatcherSample { services.AddSingleton(); services.AddSingleton(); + services.AddDispatcher(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) @@ -27,47 +26,7 @@ namespace DispatcherSample await next.Invoke(); }); - var dictionary = new Dictionary - { - { - "/example", - new DispatcherFeature - { - Endpoint = new DispatcherEndpoint("example"), - RequestDelegate = async (context) => - { - await context.Response.WriteAsync("Hello from the example!"); - } - } - }, - { - "/example2", - new DispatcherFeature - { - Endpoint = new DispatcherEndpoint("example2"), - RequestDelegate = async (context) => - { - await context.Response.WriteAsync("Hello from the second example!"); - } - } - }, - }; - - app.Use(async (context, next) => - { - if (dictionary.TryGetValue(context.Request.Path, out var value)) - { - var dispatcherFeature = new DispatcherFeature - { - Endpoint = value.Endpoint, - RequestDelegate = value.RequestDelegate - }; - - context.Features.Set(dispatcherFeature); - await context.Response.WriteAsync("

Dispatch

"); - await next.Invoke(); - } - }); + app.UseDispatcher(); app.Use(async (context, next) => { @@ -76,17 +35,11 @@ namespace DispatcherSample }); app.Use(async (context, next) => - { - var feature = context.Features.Get(); - await feature.RequestDelegate(context); - await next.Invoke(); - }); - - app.Run(async (context) => { var urlGenerator = app.ApplicationServices.GetService(); var url = urlGenerator.GenerateURL(new RouteValueDictionary(new { Movie = "The Lion King", Character = "Mufasa" }), context); await context.Response.WriteAsync($"

Generated url: {url}

"); + await next.Invoke(); }); } } diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherApplicationBuilderExtensions.cs b/src/Microsoft.AspNetCore.Dispatcher/DispatcherApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..55a04b0211 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/DispatcherApplicationBuilderExtensions.cs @@ -0,0 +1,16 @@ +// 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.Dispatcher; + +namespace Microsoft.AspNetCore.Builder +{ + public static class DispatcherApplicationBuilderExtensions + { + public static IApplicationBuilder UseDispatcher(this IApplicationBuilder builder) + { + builder.Properties.Add("Dispatcher", true); + return builder.UseMiddleware(); + } + } +} diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherEndpoint.cs b/src/Microsoft.AspNetCore.Dispatcher/DispatcherEndpoint.cs new file mode 100644 index 0000000000..ea89051708 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/DispatcherEndpoint.cs @@ -0,0 +1,15 @@ +// 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. + +namespace Microsoft.AspNetCore.Dispatcher +{ + public class DispatcherEndpoint : Endpoint + { + public DispatcherEndpoint(string displayName) + { + DisplayName = displayName; + } + + public override string DisplayName { get; } + } +} diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherEndpointStartupFilter.cs b/src/Microsoft.AspNetCore.Dispatcher/DispatcherEndpointStartupFilter.cs new file mode 100644 index 0000000000..4e40e1e640 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/DispatcherEndpointStartupFilter.cs @@ -0,0 +1,24 @@ +// 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; + +namespace Microsoft.AspNetCore.Dispatcher +{ + public class DispatcherEndpointStartupFilter : IStartupFilter + { + public Action Configure(Action next) + { + return builder => + { + next(builder); + if (builder.Properties.ContainsKey("Dispatcher")) + { + builder.UseMiddleware(); + } + }; + } + } +} diff --git a/samples/DispatcherSample/DispatcherFeature.cs b/src/Microsoft.AspNetCore.Dispatcher/DispatcherFeature.cs similarity index 92% rename from samples/DispatcherSample/DispatcherFeature.cs rename to src/Microsoft.AspNetCore.Dispatcher/DispatcherFeature.cs index 69dd17a60b..a33f2f41f1 100644 --- a/samples/DispatcherSample/DispatcherFeature.cs +++ b/src/Microsoft.AspNetCore.Dispatcher/DispatcherFeature.cs @@ -1,10 +1,9 @@ // 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.Dispatcher; using Microsoft.AspNetCore.Http; -namespace DispatcherSample +namespace Microsoft.AspNetCore.Dispatcher { public class DispatcherFeature : IDispatcherFeature { diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherMiddleware.cs b/src/Microsoft.AspNetCore.Dispatcher/DispatcherMiddleware.cs new file mode 100644 index 0000000000..fd39f52633 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/DispatcherMiddleware.cs @@ -0,0 +1,60 @@ +// 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.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNetCore.Dispatcher +{ + public class DispatcherMiddleware + { + private readonly RequestDelegate _next; + + public DispatcherMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext httpContext) + { + var dictionary = new Dictionary + { + { + "/example", + new DispatcherFeature + { + Endpoint = new DispatcherEndpoint("example"), + RequestDelegate = async (context) => + { + await context.Response.WriteAsync("Hello from the example!"); + } + } + }, + { + "/example2", + new DispatcherFeature + { + Endpoint = new DispatcherEndpoint("example2"), + RequestDelegate = async (context) => + { + await context.Response.WriteAsync("Hello from the second example!"); + } + } + }, + }; + + if (dictionary.TryGetValue(httpContext.Request.Path, out var value)) + { + var dispatcherFeature = new DispatcherFeature + { + Endpoint = value.Endpoint, + RequestDelegate = value.RequestDelegate + }; + + httpContext.Features.Set(dispatcherFeature); + await _next(httpContext); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.Dispatcher/DispatcherServiceCollectionExtensions.cs new file mode 100644 index 0000000000..e3c6fe7021 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/DispatcherServiceCollectionExtensions.cs @@ -0,0 +1,23 @@ +// 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.Dispatcher; +using Microsoft.AspNetCore.Hosting; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class DispatcherServiceCollectionExtensions + { + public static IServiceCollection AddDispatcher(this IServiceCollection services) + { + if (services == null) + { + throw new ArgumentNullException(nameof(services)); + } + + services.AddSingleton(); + return services; + } + } +} diff --git a/src/Microsoft.AspNetCore.Dispatcher/EndpointMiddleware.cs b/src/Microsoft.AspNetCore.Dispatcher/EndpointMiddleware.cs new file mode 100644 index 0000000000..363059fae6 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/EndpointMiddleware.cs @@ -0,0 +1,31 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNetCore.Dispatcher +{ + public class EndpointMiddleware + { + private RequestDelegate _next; + + public EndpointMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + var feature = context.Features.Get(); + if (feature.RequestDelegate == null) + { + await _next(context); + } + else + { + await feature.RequestDelegate(context); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Dispatcher/Microsoft.AspNetCore.Dispatcher.csproj b/src/Microsoft.AspNetCore.Dispatcher/Microsoft.AspNetCore.Dispatcher.csproj index 388054bd52..3ef72ce7a1 100644 --- a/src/Microsoft.AspNetCore.Dispatcher/Microsoft.AspNetCore.Dispatcher.csproj +++ b/src/Microsoft.AspNetCore.Dispatcher/Microsoft.AspNetCore.Dispatcher.csproj @@ -12,6 +12,7 @@ +