diff --git a/samples/DispatcherSample/DispatcherSample.csproj b/samples/DispatcherSample/DispatcherSample.csproj index 129261e276..7151f7ad15 100644 --- a/samples/DispatcherSample/DispatcherSample.csproj +++ b/samples/DispatcherSample/DispatcherSample.csproj @@ -8,6 +8,8 @@ + + diff --git a/samples/DispatcherSample/RouteValueAddress.cs b/samples/DispatcherSample/RouteValueAddress.cs new file mode 100644 index 0000000000..5f2923c447 --- /dev/null +++ b/samples/DispatcherSample/RouteValueAddress.cs @@ -0,0 +1,22 @@ +using System; +// 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.Routing; + +namespace DispatcherSample +{ + public class RouteValueAddress : Address + { + public RouteValueAddress(string displayName, RouteValueDictionary dictionary) + { + DisplayName = displayName; + RouteValueDictionary = dictionary; + } + + public override string DisplayName { get; } + + public RouteValueDictionary RouteValueDictionary { get; set; } + } +} diff --git a/samples/DispatcherSample/RouteValueAddressTable.cs b/samples/DispatcherSample/RouteValueAddressTable.cs new file mode 100644 index 0000000000..f61dcf472f --- /dev/null +++ b/samples/DispatcherSample/RouteValueAddressTable.cs @@ -0,0 +1,28 @@ +// 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.Routing; + +namespace DispatcherSample +{ + public class RouteValueAddressTable + { + public IList Addresses + { + get + { + var addresses = new List + { + new RouteValueAddress("Mickey", new RouteValueDictionary (new { Character = "Mickey" })), + new RouteValueAddress("Hakuna Matata", new RouteValueDictionary (new { Movie = "The Lion King"})), + new RouteValueAddress("Simba", new RouteValueDictionary (new { Movie = "The Lion King", Character = "Simba" })), + new RouteValueAddress("Mufasa", new RouteValueDictionary (new { Movie = "The Lion King", Character = "Mufasa" })), + new RouteValueAddress("Aladdin", new RouteValueDictionary (new { Movie = "Aladdin", Character = "Genie" })), + }; + + return addresses; + } + } + } +} diff --git a/samples/DispatcherSample/Startup.cs b/samples/DispatcherSample/Startup.cs index ac14d28d7e..38314595bc 100644 --- a/samples/DispatcherSample/Startup.cs +++ b/samples/DispatcherSample/Startup.cs @@ -1,12 +1,12 @@ // 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 System.Collections.Generic; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Dispatcher; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; namespace DispatcherSample @@ -15,6 +15,8 @@ namespace DispatcherSample { public void ConfigureServices(IServiceCollection services) { + services.AddSingleton(); + services.AddSingleton(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) @@ -55,9 +57,12 @@ namespace DispatcherSample { if (dictionary.TryGetValue(context.Request.Path, out var value)) { - var dispatcherFeature = new DispatcherFeature(); - dispatcherFeature.Endpoint = value.Endpoint; - dispatcherFeature.RequestDelegate = value.RequestDelegate; + var dispatcherFeature = new DispatcherFeature + { + Endpoint = value.Endpoint, + RequestDelegate = value.RequestDelegate + }; + context.Features.Set(dispatcherFeature); await context.Response.WriteAsync("

Dispatch

"); await next.Invoke(); @@ -70,10 +75,18 @@ namespace DispatcherSample await next.Invoke(); }); - app.Run(async (context) => + 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}

"); }); } } diff --git a/samples/DispatcherSample/UrlGenerator.cs b/samples/DispatcherSample/UrlGenerator.cs new file mode 100644 index 0000000000..9b7dca1d09 --- /dev/null +++ b/samples/DispatcherSample/UrlGenerator.cs @@ -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 Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; + +namespace DispatcherSample +{ + public class UrlGenerator + { + private readonly RouteValueAddressTable _addressTable; + + public UrlGenerator(RouteValueAddressTable addressTable) + { + _addressTable = addressTable; + } + + //Find match from values to a template + public string GenerateURL(RouteValueDictionary routeValues, HttpContext context) + { + var address = FindAddress(_addressTable, routeValues); + return $"RouteName: {address.DisplayName} URL: /{address.RouteValueDictionary["Character"]}/{address.RouteValueDictionary["Movie"]}"; + } + + //Look up the Addresses table + private RouteValueAddress FindAddress(RouteValueAddressTable addressTable, RouteValueDictionary routeValues) + { + var addressMatch = new RouteValueAddress(null, new RouteValueDictionary()); + foreach (var address in addressTable.Addresses) + { + foreach (var key in address.RouteValueDictionary.Keys) + { + if (!routeValues.Keys.Contains(key)) + { + addressMatch.RouteValueDictionary.Clear(); + break; + } + + if (routeValues.Values.Contains(address.RouteValueDictionary[key])) + { + addressMatch.RouteValueDictionary[key] = routeValues[key]; + } + } + + if (addressMatch.RouteValueDictionary.Count == routeValues.Count) + { + return new RouteValueAddress(address.DisplayName, address.RouteValueDictionary); + } + else + { + addressMatch.RouteValueDictionary.Clear(); + } + } + + return addressMatch; + } + } +}