diff --git a/samples/DispatcherSample/HttpMethodEndpointSelector.cs b/samples/DispatcherSample/HttpMethodEndpointSelector.cs index 16b43234df..594193885f 100644 --- a/samples/DispatcherSample/HttpMethodEndpointSelector.cs +++ b/samples/DispatcherSample/HttpMethodEndpointSelector.cs @@ -23,11 +23,11 @@ namespace DispatcherSample for (var i = context.Endpoints.Count - 1; i >= 0; i--) { var endpoint = context.Endpoints[i]; - IHttpMethodMetadata metadata = null; + ITemplateEndpoint metadata = null; for (var j = endpoint.Metadata.Count - 1; j >= 0; j--) { - metadata = endpoint.Metadata[j] as IHttpMethodMetadata; + metadata = endpoint.Metadata[j] as ITemplateEndpoint; if (metadata != null) { break; @@ -70,17 +70,9 @@ namespace DispatcherSample } } - private bool Matches(IHttpMethodMetadata metadata, string httpMethod) + private bool Matches(ITemplateEndpoint endpoint, string httpMethod) { - for (var i = 0; i < metadata.AllowedMethods.Count; i++) - { - if (string.Equals(metadata.AllowedMethods[i], httpMethod, StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - - return false; + return string.Equals(endpoint.HttpMethod, httpMethod, StringComparison.OrdinalIgnoreCase); } } } diff --git a/samples/DispatcherSample/HttpMethodMetadata.cs b/samples/DispatcherSample/HttpMethodMetadata.cs deleted file mode 100644 index c2266ead8c..0000000000 --- a/samples/DispatcherSample/HttpMethodMetadata.cs +++ /dev/null @@ -1,23 +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 System.Collections.Generic; - -namespace DispatcherSample -{ - public class HttpMethodMetadata : IHttpMethodMetadata - { - public HttpMethodMetadata(string httpMethod) - { - if (httpMethod == null) - { - throw new ArgumentNullException(nameof(httpMethod)); - } - - AllowedMethods = new[] { httpMethod, }; - } - - public IReadOnlyList AllowedMethods { get; } - } -} diff --git a/samples/DispatcherSample/IHttpMethodMetadata.cs b/samples/DispatcherSample/IHttpMethodMetadata.cs deleted file mode 100644 index b12731d8df..0000000000 --- a/samples/DispatcherSample/IHttpMethodMetadata.cs +++ /dev/null @@ -1,12 +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.Collections.Generic; - -namespace DispatcherSample -{ - public interface IHttpMethodMetadata - { - IReadOnlyList AllowedMethods { get; } - } -} diff --git a/samples/DispatcherSample/Startup.cs b/samples/DispatcherSample/Startup.cs index 0f561a3147..01681344c3 100644 --- a/samples/DispatcherSample/Startup.cs +++ b/samples/DispatcherSample/Startup.cs @@ -1,7 +1,6 @@ // 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.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; @@ -32,27 +31,27 @@ namespace DispatcherSample { Addresses = { - new DispatcherValueAddress(new { controller = "Home", action = "Index", }, new object[]{ new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), }, "Home:Index()"), - new DispatcherValueAddress(new { controller = "Home", action = "About", }, new object[]{ new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), }, "Home:About()"), - new DispatcherValueAddress(new { controller = "Admin", action = "Index", }, new object[]{ new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), }, "Admin:Index()"), - new DispatcherValueAddress(new { controller = "Admin", action = "Users", }, new object[]{ new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), }, "Admin:GetUsers()/Admin:EditUsers()"), + new TemplateAddress("{controller=Home}/{action=Index}/{id?}", new { controller = "Home", action = "Index", }, "Home:Index()"), + new TemplateAddress("{controller=Home}/{action=Index}/{id?}", new { controller = "Home", action = "About", }, "Home:About()"), + new TemplateAddress("{controller=Home}/{action=Index}/{id?}", new { controller = "Admin", action = "Index", }, "Admin:Index()"), + new TemplateAddress("{controller=Home}/{action=Index}/{id?}", new { controller = "Admin", action = "Users", }, "Admin:GetUsers()/Admin:EditUsers()"), }, Endpoints = { - new SimpleEndpoint(Home_Index, new object[] { new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), }, new { controller = "Home", action = "Index", }, "Home:Index()"), - new SimpleEndpoint(Home_About, new object[] { new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), }, new { controller = "Home", action = "About", }, "Home:About()"), - new SimpleEndpoint(Admin_Index, new object[] { new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), }, new { controller = "Admin", action = "Index", }, "Admin:Index()"), - new SimpleEndpoint(Admin_GetUsers, new object[] { new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), new HttpMethodMetadata("GET"), new AuthorizationPolicyMetadata("Admin"), }, new { controller = "Admin", action = "Users", }, "Admin:GetUsers()"), - new SimpleEndpoint(Admin_EditUsers, new object[] { new RouteTemplateMetadata("{controller=Home}/{action=Index}/{id?}"), new HttpMethodMetadata("POST"), new AuthorizationPolicyMetadata("Admin"), }, new { controller = "Admin", action = "Users", }, "Admin:EditUsers()"), + new TemplateEndpoint("{controller=Home}/{action=Index}/{id?}", new { controller = "Home", action = "Index", }, Home_Index, "Home:Index()"), + new TemplateEndpoint("{controller=Home}/{action=Index}/{id?}", new { controller = "Home", action = "About", }, Home_About, "Home:About()"), + new TemplateEndpoint("{controller=Home}/{action=Index}/{id?}", new { controller = "Admin", action = "Index", }, Admin_Index, "Admin:Index()"), + new TemplateEndpoint("{controller=Home}/{action=Index}/{id?}", new { controller = "Admin", action = "Users", }, "GET", Admin_GetUsers, "Admin:GetUsers()", new AuthorizationPolicyMetadata("Admin")), + new TemplateEndpoint("{controller=Home}/{action=Index}/{id?}", new { controller = "Admin", action = "Users", }, "POST", Admin_EditUsers, "Admin:EditUsers()", new AuthorizationPolicyMetadata("Admin")), }, Selectors = { - new DispatcherValueEndpointSelector(), + new TemplateEndpointSelector(), new HttpMethodEndpointSelector(), } }); - options.HandlerFactories.Add((endpoint) => (endpoint as SimpleEndpoint)?.HandlerFactory); + options.HandlerFactories.Add((endpoint) => (endpoint as TemplateEndpoint)?.HandlerFactory); }); services.AddDispatcher(); diff --git a/src/Microsoft.AspNetCore.Dispatcher/SimpleDispatcherDataSource.cs b/src/Microsoft.AspNetCore.Dispatcher/DefaultDispatcherDataSource.cs similarity index 89% rename from src/Microsoft.AspNetCore.Dispatcher/SimpleDispatcherDataSource.cs rename to src/Microsoft.AspNetCore.Dispatcher/DefaultDispatcherDataSource.cs index 4fa5b6ff5a..026f3b2167 100644 --- a/src/Microsoft.AspNetCore.Dispatcher/SimpleDispatcherDataSource.cs +++ b/src/Microsoft.AspNetCore.Dispatcher/DefaultDispatcherDataSource.cs @@ -7,12 +7,12 @@ using Microsoft.Extensions.Primitives; namespace Microsoft.AspNetCore.Dispatcher { - public class SimpleDispatcherDataSource : DispatcherDataSource + public class DefaultDispatcherDataSource : DispatcherDataSource { private readonly List
_addresses; private readonly List _endpoints; - public SimpleDispatcherDataSource() + public DefaultDispatcherDataSource() { _addresses = new List
(); _endpoints = new List(); diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.Dispatcher/DispatcherServiceCollectionExtensions.cs index 23d5a6fdd9..60279ccb11 100644 --- a/src/Microsoft.AspNetCore.Dispatcher/DispatcherServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNetCore.Dispatcher/DispatcherServiceCollectionExtensions.cs @@ -18,7 +18,7 @@ namespace Microsoft.Extensions.DependencyInjection services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); return services; } diff --git a/src/Microsoft.AspNetCore.Dispatcher/IDispatcherValueSelectableEndpoint.cs b/src/Microsoft.AspNetCore.Dispatcher/ITemplateAddress.cs similarity index 79% rename from src/Microsoft.AspNetCore.Dispatcher/IDispatcherValueSelectableEndpoint.cs rename to src/Microsoft.AspNetCore.Dispatcher/ITemplateAddress.cs index 61688390ae..dc4697b29e 100644 --- a/src/Microsoft.AspNetCore.Dispatcher/IDispatcherValueSelectableEndpoint.cs +++ b/src/Microsoft.AspNetCore.Dispatcher/ITemplateAddress.cs @@ -3,8 +3,10 @@ namespace Microsoft.AspNetCore.Dispatcher { - public interface IDispatcherValueSelectableEndpoint + public interface ITemplateAddress { + string Template { get; } + DispatcherValueCollection Values { get; } } } diff --git a/src/Microsoft.AspNetCore.Dispatcher/ITemplateEndpoint.cs b/src/Microsoft.AspNetCore.Dispatcher/ITemplateEndpoint.cs new file mode 100644 index 0000000000..06c9c6b091 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/ITemplateEndpoint.cs @@ -0,0 +1,14 @@ +// 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 interface ITemplateEndpoint + { + string HttpMethod { get; } + + string Template { get; } + + DispatcherValueCollection Values { get; } + } +} diff --git a/src/Microsoft.AspNetCore.Dispatcher/SimpleEndpoint.cs b/src/Microsoft.AspNetCore.Dispatcher/SimpleEndpoint.cs deleted file mode 100644 index 5b81776fc0..0000000000 --- a/src/Microsoft.AspNetCore.Dispatcher/SimpleEndpoint.cs +++ /dev/null @@ -1,82 +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 System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Http; - -namespace Microsoft.AspNetCore.Dispatcher -{ - public class SimpleEndpoint : Endpoint, IDispatcherValueSelectableEndpoint - { - public SimpleEndpoint(RequestDelegate requestDelegate) - : this(requestDelegate, Array.Empty(), null, null) - { - } - - public SimpleEndpoint(Func delegateFactory) - : this(delegateFactory, Array.Empty(), null, null) - { - } - - public SimpleEndpoint(RequestDelegate requestDelegate, IEnumerable metadata) - : this(requestDelegate, metadata, null, null) - { - } - - public SimpleEndpoint(Func delegateFactory, IEnumerable metadata) - : this(delegateFactory, metadata, null, null) - { - } - - public SimpleEndpoint(Func delegateFactory, IEnumerable metadata, object values) - : this(delegateFactory, metadata, null, null) - { - } - - public SimpleEndpoint(RequestDelegate requestDelegate, IEnumerable metadata, object values, string displayName) - { - if (metadata == null) - { - throw new ArgumentNullException(nameof(metadata)); - } - - if (requestDelegate == null) - { - throw new ArgumentNullException(nameof(requestDelegate)); - } - - HandlerFactory = (next) => requestDelegate; - Metadata = metadata.ToArray(); - Values = new DispatcherValueCollection(values); - DisplayName = displayName; - } - - public SimpleEndpoint(Func delegateFactory, IEnumerable metadata, object values, string displayName) - { - if (metadata == null) - { - throw new ArgumentNullException(nameof(metadata)); - } - - if (delegateFactory == null) - { - throw new ArgumentNullException(nameof(delegateFactory)); - } - - HandlerFactory = delegateFactory; - Metadata = metadata.ToArray(); - Values = new DispatcherValueCollection(values); - DisplayName = displayName; - } - - public override string DisplayName { get; } - - public override IReadOnlyList Metadata { get; } - - public Func HandlerFactory { get; } - - public DispatcherValueCollection Values { get; } - } -} diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherValueAddress.cs b/src/Microsoft.AspNetCore.Dispatcher/TemplateAddress.cs similarity index 61% rename from src/Microsoft.AspNetCore.Dispatcher/DispatcherValueAddress.cs rename to src/Microsoft.AspNetCore.Dispatcher/TemplateAddress.cs index 065f56eb7b..606f9997f2 100644 --- a/src/Microsoft.AspNetCore.Dispatcher/DispatcherValueAddress.cs +++ b/src/Microsoft.AspNetCore.Dispatcher/TemplateAddress.cs @@ -7,24 +7,18 @@ using System.Linq; namespace Microsoft.AspNetCore.Dispatcher { - public class DispatcherValueAddress : Address + public class TemplateAddress : Address, ITemplateAddress { - public DispatcherValueAddress(object values) - : this(values, Array.Empty(), null) + public TemplateAddress(string template, object values, params object[] metadata) + : this(template, values, null, metadata) { } - - public DispatcherValueAddress(object values, IEnumerable metadata) - : this(values, metadata, null) + public TemplateAddress(string template, object values, string displayName, params object[] metadata) { - } - - public DispatcherValueAddress(object values, IEnumerable metadata, string displayName) - { - if (values == null) + if (template == null) { - throw new ArgumentNullException(nameof(values)); + throw new ArgumentNullException(nameof(template)); } if (metadata == null) @@ -32,15 +26,18 @@ namespace Microsoft.AspNetCore.Dispatcher throw new ArgumentNullException(nameof(metadata)); } + Template = template; Values = new DispatcherValueCollection(values); - Metadata = metadata.ToArray(); DisplayName = displayName; + Metadata = metadata.ToArray(); } public override string DisplayName { get; } public override IReadOnlyList Metadata { get; } + public string Template { get; } + public DispatcherValueCollection Values { get; } } } diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherValueAddressSelector.cs b/src/Microsoft.AspNetCore.Dispatcher/TemplateAddressSelector.cs similarity index 87% rename from src/Microsoft.AspNetCore.Dispatcher/DispatcherValueAddressSelector.cs rename to src/Microsoft.AspNetCore.Dispatcher/TemplateAddressSelector.cs index d7adebfe5e..efb405f6bf 100644 --- a/src/Microsoft.AspNetCore.Dispatcher/DispatcherValueAddressSelector.cs +++ b/src/Microsoft.AspNetCore.Dispatcher/TemplateAddressSelector.cs @@ -7,11 +7,11 @@ using System.Collections.Generic; namespace Microsoft.AspNetCore.Dispatcher { // This isn't a proposed design, just a placeholder to demonstrate that things are wired up correctly. - public class DispatcherValueAddressSelector + public class TemplateAddressSelector { private readonly AddressTable _addressTable; - public DispatcherValueAddressSelector(AddressTable addressTable) + public TemplateAddressSelector(AddressTable addressTable) { if (addressTable == null) { @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Dispatcher for (var j = 0; j < group.Count; j++) { - var address = group[j] as DispatcherValueAddress; + var address = group[j] as ITemplateAddress; if (address == null) { continue; @@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Dispatcher if (IsMatch(address, values)) { - matches.Add(address); + matches.Add(group[j]); } } @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Dispatcher return null; } - private bool IsMatch(DispatcherValueAddress address, DispatcherValueCollection values) + private bool IsMatch(ITemplateAddress address, DispatcherValueCollection values) { foreach (var kvp in address.Values) { diff --git a/src/Microsoft.AspNetCore.Dispatcher/TemplateEndpoint.cs b/src/Microsoft.AspNetCore.Dispatcher/TemplateEndpoint.cs new file mode 100644 index 0000000000..3618e726c4 --- /dev/null +++ b/src/Microsoft.AspNetCore.Dispatcher/TemplateEndpoint.cs @@ -0,0 +1,127 @@ +// 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 System.Linq; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNetCore.Dispatcher +{ + public class TemplateEndpoint : Endpoint, ITemplateEndpoint + { + public TemplateEndpoint(string template, RequestDelegate requestDelegate, params object[] metadata) + : this(template, (object)null, (string)null, requestDelegate, null, metadata) + { + } + + public TemplateEndpoint(string template, Func delegateFactory, params object[] metadata) + : this(template, (object)null, (string)null, delegateFactory, null, metadata) + { + } + + public TemplateEndpoint(string template, object values, RequestDelegate requestDelegate, params object[] metadata) + : this(template, values, null, requestDelegate, null, metadata) + { + } + + public TemplateEndpoint(string template, object values, Func delegateFactory, params object[] metadata) + : this(template, values, null, delegateFactory, null, metadata) + { + } + + public TemplateEndpoint(string template, object values, RequestDelegate requestDelegate, string displayName, params object[] metadata) + : this(template, values, null, requestDelegate, displayName, metadata) + { + } + + public TemplateEndpoint(string template, object values, Func delegateFactory, string displayName, params object[] metadata) + : this(template, values, null, delegateFactory, displayName, metadata) + { + } + + public TemplateEndpoint(string template, object values, string httpMethod, RequestDelegate requestDelegate, params object[] metadata) + : this(template, values, httpMethod, requestDelegate, null, metadata) + { + } + + public TemplateEndpoint(string template, object values, string httpMethod, Func delegateFactory, params object[] metadata) + : this(template, values, httpMethod, delegateFactory, null, metadata) + { + } + + public TemplateEndpoint( + string template, + object values, + string httpMethod, + RequestDelegate requestDelegate, + string displayName, + params object[] metadata) + { + if (template == null) + { + throw new ArgumentNullException(nameof(template)); + } + + if (requestDelegate == null) + { + throw new ArgumentNullException(nameof(requestDelegate)); + } + + if (metadata == null) + { + throw new ArgumentNullException(nameof(metadata)); + } + + Template = template; + Values = new DispatcherValueCollection(values); + HttpMethod = httpMethod; + HandlerFactory = (next) => requestDelegate; + DisplayName = displayName; + Metadata = metadata.ToArray(); + } + + public TemplateEndpoint( + string template, + object values, + string httpMethod, + Func delegateFactory, + string displayName, + params object[] metadata) + { + if (template == null) + { + throw new ArgumentNullException(nameof(template)); + } + + if (delegateFactory == null) + { + throw new ArgumentNullException(nameof(delegateFactory)); + } + + if (metadata == null) + { + throw new ArgumentNullException(nameof(metadata)); + } + + Template = template; + Values = new DispatcherValueCollection(values); + HttpMethod = httpMethod; + HandlerFactory = delegateFactory; + DisplayName = displayName; + Metadata = metadata.ToArray(); + } + + public override string DisplayName { get; } + + public string HttpMethod { get; } + + public override IReadOnlyList Metadata { get; } + + public Func HandlerFactory { get; } + + public string Template { get; } + + public DispatcherValueCollection Values { get; } + } +} diff --git a/src/Microsoft.AspNetCore.Dispatcher/DispatcherValueEndpointSelector.cs b/src/Microsoft.AspNetCore.Dispatcher/TemplateEndpointSelector.cs similarity index 91% rename from src/Microsoft.AspNetCore.Dispatcher/DispatcherValueEndpointSelector.cs rename to src/Microsoft.AspNetCore.Dispatcher/TemplateEndpointSelector.cs index a8377321f1..3e2a2d6bb9 100644 --- a/src/Microsoft.AspNetCore.Dispatcher/DispatcherValueEndpointSelector.cs +++ b/src/Microsoft.AspNetCore.Dispatcher/TemplateEndpointSelector.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Microsoft.AspNetCore.Dispatcher { - public class DispatcherValueEndpointSelector : EndpointSelector + public class TemplateEndpointSelector : EndpointSelector { public override Task SelectAsync(EndpointSelectorContext context) { @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Dispatcher for (var i = context.Endpoints.Count - 1; i >= 0; i--) { - var endpoint = context.Endpoints[i] as IDispatcherValueSelectableEndpoint; + var endpoint = context.Endpoints[i] as ITemplateEndpoint; if (!CompareRouteValues(dispatcherFeature.Values, endpoint.Values)) { context.Endpoints.RemoveAt(i); diff --git a/src/Microsoft.AspNetCore.Routing/Dispatcher/IRouteTemplateMetadata.cs b/src/Microsoft.AspNetCore.Routing/Dispatcher/IRouteTemplateMetadata.cs deleted file mode 100644 index 13f30517b2..0000000000 --- a/src/Microsoft.AspNetCore.Routing/Dispatcher/IRouteTemplateMetadata.cs +++ /dev/null @@ -1,14 +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.Dispatcher; - -namespace Microsoft.AspNetCore.Routing.Dispatcher -{ - public interface IRouteTemplateMetadata - { - string RouteTemplate { get; } - - DispatcherValueCollection Defaults { get; } - } -} diff --git a/src/Microsoft.AspNetCore.Routing/Dispatcher/ITreeDispatcherMetadata.cs b/src/Microsoft.AspNetCore.Routing/Dispatcher/ITreeDispatcherMetadata.cs deleted file mode 100644 index 27ad992905..0000000000 --- a/src/Microsoft.AspNetCore.Routing/Dispatcher/ITreeDispatcherMetadata.cs +++ /dev/null @@ -1,12 +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. - -namespace Microsoft.AspNetCore.Routing.Dispatcher -{ - public interface ITreeDispatcherMetadata - { - int Order { get; } - - string RouteTemplate { get; } - } -} diff --git a/src/Microsoft.AspNetCore.Routing/Dispatcher/RouteTemplateMetadata.cs b/src/Microsoft.AspNetCore.Routing/Dispatcher/RouteTemplateMetadata.cs deleted file mode 100644 index 8416c422a7..0000000000 --- a/src/Microsoft.AspNetCore.Routing/Dispatcher/RouteTemplateMetadata.cs +++ /dev/null @@ -1,33 +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.Dispatcher; - -namespace Microsoft.AspNetCore.Routing.Dispatcher -{ - public class RouteTemplateMetadata : IRouteTemplateMetadata, ITreeDispatcherMetadata - { - public RouteTemplateMetadata(string routeTemplate) - : this(routeTemplate, null) - { - } - - public RouteTemplateMetadata(string routeTemplate, object defaults) - { - if (routeTemplate == null) - { - throw new ArgumentNullException(nameof(routeTemplate)); - } - - RouteTemplate = routeTemplate; - Defaults = new DispatcherValueCollection(defaults); - } - - public string RouteTemplate { get; } - - public DispatcherValueCollection Defaults { get; } - - public int Order { get; set; } - } -} diff --git a/src/Microsoft.AspNetCore.Routing/Dispatcher/RouteTemplateUrlGenerator.cs b/src/Microsoft.AspNetCore.Routing/Dispatcher/RouteTemplateUrlGenerator.cs index 604f3c394a..ac7bf97a56 100644 --- a/src/Microsoft.AspNetCore.Routing/Dispatcher/RouteTemplateUrlGenerator.cs +++ b/src/Microsoft.AspNetCore.Routing/Dispatcher/RouteTemplateUrlGenerator.cs @@ -14,11 +14,11 @@ namespace Microsoft.AspNetCore.Routing.Dispatcher // This isn't a proposed design, just a placeholder to demonstrate that things are wired up correctly. public class RouteTemplateUrlGenerator { - private readonly DispatcherValueAddressSelector _addressSelector; + private readonly TemplateAddressSelector _addressSelector; private readonly ObjectPool _pool; private readonly UrlEncoder _urlEncoder; - public RouteTemplateUrlGenerator(DispatcherValueAddressSelector addressSelector, UrlEncoder urlEncoder, ObjectPool pool) + public RouteTemplateUrlGenerator(TemplateAddressSelector addressSelector, UrlEncoder urlEncoder, ObjectPool pool) { _addressSelector = addressSelector; _urlEncoder = urlEncoder; @@ -37,14 +37,13 @@ namespace Microsoft.AspNetCore.Routing.Dispatcher throw new ArgumentNullException(nameof(values)); } - var address = _addressSelector.SelectAddress(new DispatcherValueCollection(values)); + var address = _addressSelector.SelectAddress(new DispatcherValueCollection(values)) as ITemplateAddress; if (address == null) { throw new InvalidOperationException("Can't find address"); } - var (template, defaults) = GetRouteTemplate(address); - var binder = new TemplateBinder(_urlEncoder, _pool, TemplateParser.Parse(template), defaults.AsRouteValueDictionary()); + var binder = new TemplateBinder(_urlEncoder, _pool, TemplateParser.Parse(address.Template), new RouteValueDictionary()); var feature = httpContext.Features.Get(); var result = binder.GetValues(feature.Values.AsRouteValueDictionary(), new RouteValueDictionary(values)); @@ -55,18 +54,5 @@ namespace Microsoft.AspNetCore.Routing.Dispatcher return binder.BindValues(result.AcceptedValues); } - private (string, DispatcherValueCollection) GetRouteTemplate(Address address) - { - for (var i = address.Metadata.Count - 1; i >= 0; i--) - { - var metadata = address.Metadata[i] as IRouteTemplateMetadata; - if (metadata != null) - { - return (metadata.RouteTemplate, metadata.Defaults); - } - } - - return (null, null); - } } } diff --git a/src/Microsoft.AspNetCore.Routing/Dispatcher/TreeDispatcher.cs b/src/Microsoft.AspNetCore.Routing/Dispatcher/TreeDispatcher.cs index 223b7e271e..b2ebd951d0 100644 --- a/src/Microsoft.AspNetCore.Routing/Dispatcher/TreeDispatcher.cs +++ b/src/Microsoft.AspNetCore.Routing/Dispatcher/TreeDispatcher.cs @@ -142,16 +142,16 @@ namespace Microsoft.AspNetCore.Routing.Dispatcher { var endpoint = endpoints[i]; - var metadata = endpoint.Metadata.OfType().LastOrDefault(); - if (metadata == null) + var templateEndpoint = endpoint as ITemplateEndpoint; + if (templateEndpoint == null) { continue; } - if (!groups.TryGetValue(new Key(metadata.Order, metadata.RouteTemplate), out var group)) + if (!groups.TryGetValue(new Key(0, templateEndpoint.Template), out var group)) { group = new List(); - groups.Add(new Key(metadata.Order, metadata.RouteTemplate), group); + groups.Add(new Key(0, templateEndpoint.Template), group); } group.Add(endpoint); diff --git a/test/Microsoft.AspNetCore.Dispatcher.FunctionalTest/ApiAppStartup.cs b/test/Microsoft.AspNetCore.Dispatcher.FunctionalTest/ApiAppStartup.cs index 02e8ea95ab..16db011349 100644 --- a/test/Microsoft.AspNetCore.Dispatcher.FunctionalTest/ApiAppStartup.cs +++ b/test/Microsoft.AspNetCore.Dispatcher.FunctionalTest/ApiAppStartup.cs @@ -58,11 +58,11 @@ namespace Microsoft.AspNetCore.Dispatcher.FunctionalTest { Endpoints = { - new SimpleEndpoint(Products_Get, new object[]{ new RouteTemplateMetadata("api/products"), }), + new TemplateEndpoint("api/products", Products_Get), }, }); - options.HandlerFactories.Add(endpoint => (endpoint as SimpleEndpoint)?.HandlerFactory); + options.HandlerFactories.Add(endpoint => (endpoint as TemplateEndpoint)?.HandlerFactory); } private Task Products_Get(HttpContext httpContext) => httpContext.Response.WriteAsync("Hello, Products_Get");