Simplify Map methods

This commit is contained in:
Ryan Nowak 2019-03-12 14:46:04 -07:00
parent 4b4614635f
commit 0dc14a61ce
14 changed files with 265 additions and 340 deletions

View File

@ -5,20 +5,13 @@ namespace Microsoft.AspNetCore.Builder
{
public static partial class EndpointRouteBuilderExtensions
{
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, Microsoft.AspNetCore.Routing.Patterns.RoutePattern pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, Microsoft.AspNetCore.Routing.Patterns.RoutePattern pattern, string displayName, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string displayName, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapDelete(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapDelete(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string displayName, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapGet(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapGet(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string displayName, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPost(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPost(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string displayName, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPut(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPut(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string displayName, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapVerbs(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, System.Collections.Generic.IList<string> httpMethods, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapVerbs(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string displayName, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, System.Collections.Generic.IList<string> httpMethods, params object[] metadata) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, Microsoft.AspNetCore.Routing.Patterns.RoutePattern pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapDelete(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapGet(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapMethods(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, System.Collections.Generic.IEnumerable<string> httpMethods, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPost(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPut(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
}
public static partial class EndpointRoutingApplicationBuilderExtensions
{
@ -51,6 +44,9 @@ namespace Microsoft.AspNetCore.Builder
public static partial class RoutingEndpointConventionBuilderExtensions
{
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder RequireHost(this Microsoft.AspNetCore.Builder.IEndpointConventionBuilder builder, params string[] hosts) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder WithDisplayName(this Microsoft.AspNetCore.Builder.IEndpointConventionBuilder builder, System.Func<Microsoft.AspNetCore.Builder.EndpointBuilder, string> func) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder WithDisplayName(this Microsoft.AspNetCore.Builder.IEndpointConventionBuilder builder, string displayName) { throw null; }
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder WithMetadata(this Microsoft.AspNetCore.Builder.IEndpointConventionBuilder builder, params object[] items) { throw null; }
}
}
namespace Microsoft.AspNetCore.Routing

View File

@ -29,35 +29,13 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapGet(
this IEndpointRouteBuilder routes,
string pattern,
RequestDelegate requestDelegate,
params object[] metadata)
RequestDelegate requestDelegate)
{
return MapVerbs(routes, pattern, displayName: null, requestDelegate, GetVerb, metadata);
}
/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP GET requests
/// for the specified pattern.
/// </summary>
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="displayName">The display name for the endpoint.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapGet(
this IEndpointRouteBuilder routes,
string pattern,
string displayName,
RequestDelegate requestDelegate,
params object[] metadata)
{
return MapVerbs(routes, pattern, displayName, requestDelegate, GetVerb, metadata);
return MapMethods(routes, pattern, GetVerb, requestDelegate);
}
/// <summary>
@ -67,35 +45,13 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapPost(
this IEndpointRouteBuilder routes,
string pattern,
RequestDelegate requestDelegate,
params object[] metadata)
RequestDelegate requestDelegate)
{
return MapVerbs(routes, pattern, displayName: null, requestDelegate, PostVerb, metadata);
}
/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP POST requests
/// for the specified pattern.
/// </summary>
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="displayName">The display name for the endpoint.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapPost(
this IEndpointRouteBuilder routes,
string pattern,
string displayName,
RequestDelegate requestDelegate,
params object[] metadata)
{
return MapVerbs(routes, pattern, displayName, requestDelegate, PostVerb, metadata);
return MapMethods(routes, pattern, PostVerb, requestDelegate);
}
/// <summary>
@ -105,35 +61,13 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapPut(
this IEndpointRouteBuilder routes,
string pattern,
RequestDelegate requestDelegate,
params object[] metadata)
RequestDelegate requestDelegate)
{
return MapVerbs(routes, pattern, displayName: null, requestDelegate, PutVerb, metadata);
}
/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP PUT requests
/// for the specified pattern.
/// </summary>
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="displayName">The display name for the endpoint.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapPut(
this IEndpointRouteBuilder routes,
string pattern,
string displayName,
RequestDelegate requestDelegate,
params object[] metadata)
{
return MapVerbs(routes, pattern, displayName, requestDelegate, PutVerb, metadata);
return MapMethods(routes, pattern, PutVerb, requestDelegate);
}
/// <summary>
@ -143,35 +77,13 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapDelete(
this IEndpointRouteBuilder routes,
string pattern,
RequestDelegate requestDelegate,
params object[] metadata)
RequestDelegate requestDelegate)
{
return MapVerbs(routes, pattern, displayName: null, requestDelegate, DeleteVerb, metadata);
}
/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP DELETE requests
/// for the specified pattern.
/// </summary>
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="displayName">The display name for the endpoint.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapDelete(
this IEndpointRouteBuilder routes,
string pattern,
string displayName,
RequestDelegate requestDelegate,
params object[] metadata)
{
return MapVerbs(routes, pattern, displayName, requestDelegate, DeleteVerb, metadata);
return MapMethods(routes, pattern, DeleteVerb, requestDelegate);
}
/// <summary>
@ -182,50 +94,22 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="pattern">The route pattern.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="httpMethods">HTTP methods that the endpoint will match.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapVerbs(
public static IEndpointConventionBuilder MapMethods(
this IEndpointRouteBuilder routes,
string pattern,
RequestDelegate requestDelegate,
IList<string> httpMethods,
params object[] metadata)
{
return MapVerbs(routes, pattern, displayName: null, requestDelegate, httpMethods, metadata);
}
/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP requests
/// for the specified HTTP methods and pattern.
/// </summary>
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="displayName">The display name for the endpoint.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="httpMethods">HTTP methods that the endpoint will match.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder MapVerbs(
this IEndpointRouteBuilder routes,
string pattern,
string displayName,
RequestDelegate requestDelegate,
IList<string> httpMethods,
params object[] metadata)
IEnumerable<string> httpMethods,
RequestDelegate requestDelegate)
{
if (httpMethods == null)
{
throw new ArgumentNullException(nameof(httpMethods));
}
var resolvedMetadata = new List<object>();
resolvedMetadata.Add(new HttpMethodMetadata(httpMethods));
if (metadata != null)
{
resolvedMetadata.AddRange(metadata);
}
return Map(routes, pattern, displayName ?? $"{pattern} HTTP: {string.Join(", ", httpMethods)}", requestDelegate, metadata: resolvedMetadata.ToArray());
var builder = routes.Map(RoutePatternFactory.Parse(pattern), requestDelegate);
builder.WithDisplayName($"{pattern} HTTP: {string.Join(", ", httpMethods)}");
builder.WithMetadata(new HttpMethodMetadata(httpMethods));
return builder;
}
/// <summary>
@ -235,35 +119,13 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder Map(
this IEndpointRouteBuilder routes,
string pattern,
RequestDelegate requestDelegate,
params object[] metadata)
RequestDelegate requestDelegate)
{
return Map(routes, RoutePatternFactory.Parse(pattern), pattern, requestDelegate, metadata);
}
/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP requests
/// for the specified pattern.
/// </summary>
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="displayName">The display name for the endpoint.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder Map(
this IEndpointRouteBuilder routes,
string pattern,
string displayName,
RequestDelegate requestDelegate,
params object[] metadata)
{
return Map(routes, RoutePatternFactory.Parse(pattern), displayName, requestDelegate, metadata);
return Map(routes, RoutePatternFactory.Parse(pattern), requestDelegate);
}
/// <summary>
@ -273,33 +135,11 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder Map(
this IEndpointRouteBuilder routes,
RoutePattern pattern,
RequestDelegate requestDelegate,
params object[] metadata)
{
return Map(routes, pattern, pattern.RawText ?? pattern.DebuggerToString(), requestDelegate, metadata);
}
/// <summary>
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP requests
/// for the specified pattern.
/// </summary>
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
/// <param name="pattern">The route pattern.</param>
/// <param name="displayName">The display name for the endpoint.</param>
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
/// <param name="metadata">Metadata that is added to the endpoint.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static IEndpointConventionBuilder Map(
this IEndpointRouteBuilder routes,
RoutePattern pattern,
string displayName,
RequestDelegate requestDelegate,
params object[] metadata)
RequestDelegate requestDelegate)
{
if (routes == null)
{
@ -318,12 +158,12 @@ namespace Microsoft.AspNetCore.Builder
const int defaultOrder = 0;
var routeEndpointBuilder = new RouteEndpointBuilder(
var builder = new RouteEndpointBuilder(
requestDelegate,
pattern,
defaultOrder)
{
DisplayName = displayName
DisplayName = pattern.RawText ?? pattern.DebuggerToString(),
};
// Add delegate attributes as metadata
@ -334,27 +174,18 @@ namespace Microsoft.AspNetCore.Builder
{
foreach (var attribute in attributes)
{
routeEndpointBuilder.Metadata.Add(attribute);
builder.Metadata.Add(attribute);
}
}
if (metadata != null)
var dataSource = routes.DataSources.OfType<ModelEndpointDataSource>().FirstOrDefault();
if (dataSource == null)
{
foreach (var item in metadata)
{
routeEndpointBuilder.Metadata.Add(item);
}
dataSource = new ModelEndpointDataSource();
routes.DataSources.Add(dataSource);
}
var modelEndpointDataSource = routes.DataSources.OfType<ModelEndpointDataSource>().FirstOrDefault();
if (modelEndpointDataSource == null)
{
modelEndpointDataSource = new ModelEndpointDataSource();
routes.DataSources.Add(modelEndpointDataSource);
}
return modelEndpointDataSource.AddEndpointBuilder(routeEndpointBuilder);
return dataSource.AddEndpointBuilder(builder);
}
}
}

View File

@ -87,7 +87,8 @@ namespace Microsoft.AspNetCore.Builder
throw new ArgumentNullException(nameof(requestDelegate));
}
var conventionBuilder = routes.Map(pattern, "Fallback " + pattern, requestDelegate);
var conventionBuilder = routes.Map(pattern, requestDelegate);
conventionBuilder.WithDisplayName("Fallback " + pattern);
conventionBuilder.Add(b => ((RouteEndpointBuilder)b).Order = int.MaxValue);
return conventionBuilder;
}

View File

@ -39,5 +39,84 @@ namespace Microsoft.AspNetCore.Builder
});
return builder;
}
/// <summary>
/// Sets the <see cref="EndpointBuilder.DisplayName"/> to the provided <paramref name="displayName"/> for all
/// builders created by <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
/// <param name="displayName">The display name.</param>
/// <returns>The <see cref="IEndpointConventionBuilder"/>.</returns>
public static IEndpointConventionBuilder WithDisplayName(this IEndpointConventionBuilder builder, string displayName)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Add(b =>
{
b.DisplayName = displayName;
});
return builder;
}
/// <summary>
/// Sets the <see cref="EndpointBuilder.DisplayName"/> using the provided <paramref name="func"/> for all
/// builders created by <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
/// <param name="func">A delegate that produces the display name for each <see cref="EndpointBuilder"/>.</param>
/// <returns>The <see cref="IEndpointConventionBuilder"/>.</returns>
public static IEndpointConventionBuilder WithDisplayName(this IEndpointConventionBuilder builder, Func<EndpointBuilder, string> func)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (func == null)
{
throw new ArgumentNullException(nameof(func));
}
builder.Add(b =>
{
b.DisplayName = func(b);
});
return builder;
}
/// <summary>
/// Adds the provided metadata <paramref name="items"/> to <see cref="EndpointBuilder.Metadata"/> for all builders
/// produced by <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
/// <param name="items">A collection of metadata items.</param>
/// <returns>The <see cref="IEndpointConventionBuilder"/>.</returns>
public static IEndpointConventionBuilder WithMetadata(this IEndpointConventionBuilder builder, params object[] items)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (items == null)
{
throw new ArgumentNullException(nameof(items));
}
builder.Add(b =>
{
foreach (var item in items)
{
b.Metadata.Add(item);
}
});
return builder;
}
}
}

View File

@ -0,0 +1,38 @@
// 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.Http;
namespace Microsoft.AspNetCore.Routing
{
internal class DefaultEndpointConventionBuilder : IEndpointConventionBuilder
{
internal EndpointBuilder EndpointBuilder { get; }
private readonly List<Action<EndpointBuilder>> _conventions;
public DefaultEndpointConventionBuilder(EndpointBuilder endpointBuilder)
{
EndpointBuilder = endpointBuilder;
_conventions = new List<Action<EndpointBuilder>>();
}
public void Add(Action<EndpointBuilder> convention)
{
_conventions.Add(convention);
}
public Endpoint Build()
{
foreach (var convention in _conventions)
{
convention(EndpointBuilder);
}
return EndpointBuilder.Build();
}
}
}

View File

@ -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.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Builder;
@ -13,16 +12,16 @@ namespace Microsoft.AspNetCore.Routing
{
internal class ModelEndpointDataSource : EndpointDataSource
{
private List<EndpointConventionBuilder> _endpointConventionBuilders;
private List<DefaultEndpointConventionBuilder> _endpointConventionBuilders;
public ModelEndpointDataSource()
{
_endpointConventionBuilders = new List<EndpointConventionBuilder>();
_endpointConventionBuilders = new List<DefaultEndpointConventionBuilder>();
}
public IEndpointConventionBuilder AddEndpointBuilder(EndpointBuilder endpointBuilder)
{
var builder = new EndpointConventionBuilder(endpointBuilder);
var builder = new DefaultEndpointConventionBuilder(endpointBuilder);
_endpointConventionBuilders.Add(builder);
return builder;
@ -37,33 +36,5 @@ namespace Microsoft.AspNetCore.Routing
// for testing
internal IEnumerable<EndpointBuilder> EndpointBuilders => _endpointConventionBuilders.Select(b => b.EndpointBuilder);
private class EndpointConventionBuilder : IEndpointConventionBuilder
{
internal EndpointBuilder EndpointBuilder { get; }
private readonly List<Action<EndpointBuilder>> _conventions;
public EndpointConventionBuilder(EndpointBuilder endpointBuilder)
{
EndpointBuilder = endpointBuilder;
_conventions = new List<Action<EndpointBuilder>>();
}
public void Add(Action<EndpointBuilder> convention)
{
_conventions.Add(convention);
}
public Endpoint Build()
{
foreach (var convention in _conventions)
{
convention(EndpointBuilder);
}
return EndpointBuilder.Build();
}
}
}
}

View File

@ -167,14 +167,14 @@ namespace Microsoft.AspNetCore.Builder
// Act
app.UseRouting(builder =>
{
builder.Map("/1", "Test endpoint 1", d => null);
builder.Map("/2", "Test endpoint 2", d => null);
builder.Map("/1", d => null).WithDisplayName("Test endpoint 1");
builder.Map("/2", d => null).WithDisplayName("Test endpoint 2");
});
app.UseRouting(builder =>
{
builder.Map("/3", "Test endpoint 3", d => null);
builder.Map("/4", "Test endpoint 4", d => null);
builder.Map("/3", d => null).WithDisplayName("Test endpoint 3");
builder.Map("/4", d => null).WithDisplayName("Test endpoint 4");
});
// This triggers the middleware to be created and the matcher factory to be called

View File

@ -33,13 +33,13 @@ namespace Microsoft.AspNetCore.Builder
RequestDelegate requestDelegate = (d) => null;
// Act
var endpointBuilder = builder.Map("/", "Display name!", requestDelegate);
var endpointBuilder = builder.Map("/", requestDelegate);
// Assert
var endpointBuilder1 = GetRouteEndpointBuilder(builder);
Assert.Equal(requestDelegate, endpointBuilder1.RequestDelegate);
Assert.Equal("Display name!", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.RoutePattern.RawText);
}
@ -51,54 +51,16 @@ namespace Microsoft.AspNetCore.Builder
RequestDelegate requestDelegate = (d) => null;
// Act
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), "Display name!", requestDelegate);
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), requestDelegate);
// Assert
var endpointBuilder1 = GetRouteEndpointBuilder(builder);
Assert.Equal(requestDelegate, endpointBuilder1.RequestDelegate);
Assert.Equal("Display name!", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.RoutePattern.RawText);
}
[Fact]
public void MapEndpoint_StringPatternAndMetadata_BuildsEndpoint()
{
// Arrange
var metadata = new object();
var builder = new DefaultEndpointRouteBuilder();
RequestDelegate requestDelegate = (d) => null;
// Act
var endpointBuilder = builder.Map("/", "Display name!", requestDelegate, new[] { metadata });
// Assert
var endpointBuilder1 = GetRouteEndpointBuilder(builder);
Assert.Equal(requestDelegate, endpointBuilder1.RequestDelegate);
Assert.Equal("Display name!", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.RoutePattern.RawText);
Assert.Equal(metadata, Assert.Single(endpointBuilder1.Metadata));
}
[Fact]
public void MapEndpoint_TypedPatternAndMetadata_BuildsEndpoint()
{
// Arrange
var metadata = new object();
var builder = new DefaultEndpointRouteBuilder();
RequestDelegate requestDelegate = (d) => null;
// Act
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), "Display name!", requestDelegate, new[] { metadata });
// Assert
var endpointBuilder1 = GetRouteEndpointBuilder(builder);
Assert.Equal(requestDelegate, endpointBuilder1.RequestDelegate);
Assert.Equal("Display name!", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.RoutePattern.RawText);
Assert.Equal(metadata, Assert.Single(endpointBuilder1.Metadata));
}
[Fact]
public void MapEndpoint_AttributesCollectedAsMetadata()
{
@ -106,36 +68,16 @@ namespace Microsoft.AspNetCore.Builder
var builder = new DefaultEndpointRouteBuilder();
// Act
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), "Display name!", Handle);
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), Handle);
// Assert
var endpointBuilder1 = GetRouteEndpointBuilder(builder);
Assert.Equal("Display name!", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.RoutePattern.RawText);
Assert.Equal(2, endpointBuilder1.Metadata.Count);
Assert.IsType<Attribute1>(endpointBuilder1.Metadata[0]);
Assert.IsType<Attribute2>(endpointBuilder1.Metadata[1]);
}
[Fact]
public void MapEndpoint_ExplicitMetadataAddedAfterAttributeMetadata()
{
// Arrange
var builder = new DefaultEndpointRouteBuilder();
// Act
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), "Display name!", Handle, new Metadata());
// Assert
var endpointBuilder1 = GetRouteEndpointBuilder(builder);
Assert.Equal("Display name!", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.RoutePattern.RawText);
Assert.Equal(3, endpointBuilder1.Metadata.Count);
Assert.IsType<Attribute1>(endpointBuilder1.Metadata[0]);
Assert.IsType<Attribute2>(endpointBuilder1.Metadata[1]);
Assert.IsType<Metadata>(endpointBuilder1.Metadata[2]);
}
[Fact]
public void MapEndpoint_GeneratedDelegateWorks()
{
@ -145,14 +87,11 @@ namespace Microsoft.AspNetCore.Builder
Expression<RequestDelegate> handler = context => Task.CompletedTask;
// Act
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), "Display name!", handler.Compile(), new Metadata());
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), handler.Compile());
// Assert
var endpointBuilder1 = GetRouteEndpointBuilder(builder);
Assert.Equal("Display name!", endpointBuilder1.DisplayName);
Assert.Equal("/", endpointBuilder1.RoutePattern.RawText);
Assert.Equal(1, endpointBuilder1.Metadata.Count);
Assert.IsType<Metadata>(endpointBuilder1.Metadata[0]);
}
[Fact]
@ -162,21 +101,17 @@ namespace Microsoft.AspNetCore.Builder
var builder = new DefaultEndpointRouteBuilder();
// Act
var endpointBuilder = builder.MapGet("/", HandleHttpMetdata, new HttpMethodMetadata(new[] { "METHOD" }));
endpointBuilder.Add(b =>
{
b.Metadata.Add(new HttpMethodMetadata(new[] { "BUILDER" }));
});
var endpointBuilder = builder.MapMethods("/", new[] { "METHOD" }, HandleHttpMetdata);
endpointBuilder.WithMetadata(new HttpMethodMetadata(new[] { "BUILDER" }));
// Assert
var dataSource = Assert.Single(builder.DataSources);
var endpoint = Assert.Single(dataSource.Endpoints);
Assert.Equal(4, endpoint.Metadata.Count);
Assert.Equal(3, endpoint.Metadata.Count);
Assert.Equal("ATTRIBUTE", GetMethod(endpoint.Metadata[0]));
Assert.Equal("GET", GetMethod(endpoint.Metadata[1]));
Assert.Equal("METHOD", GetMethod(endpoint.Metadata[2]));
Assert.Equal("BUILDER", GetMethod(endpoint.Metadata[3]));
Assert.Equal("METHOD", GetMethod(endpoint.Metadata[1]));
Assert.Equal("BUILDER", GetMethod(endpoint.Metadata[2]));
Assert.Equal("BUILDER", endpoint.Metadata.GetMetadata<IHttpMethodMetadata>().HttpMethods.Single());

View File

@ -0,0 +1,85 @@
// 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.Routing;
using Microsoft.AspNetCore.Routing.Patterns;
using Xunit;
namespace Microsoft.AspNetCore.Builder
{
public class RoutingEndpointConventionBuilderExtensionsTest
{
[Fact]
public void RequireHost_AddsHostMetadata()
{
// Arrange
var builder = CreateBuilder();
// Act
builder.RequireHost("www.example.com", "example.com");
// Assert
var endpoint = builder.Build();
var metadata = endpoint.Metadata.GetMetadata<IHostMetadata>();
Assert.NotNull(metadata);
Assert.Equal(new[] { "www.example.com", "example.com" }, metadata.Hosts);
}
[Fact]
public void WithDisplayName_String_SetsDisplayName()
{
// Arrange
var builder = CreateBuilder();
// Act
builder.WithDisplayName("test");
// Assert
var endpoint = builder.Build();
Assert.Equal("test", endpoint.DisplayName);
}
[Fact]
public void WithDisplayName_Func_SetsDisplayName()
{
// Arrange
var builder = CreateBuilder();
// Act
builder.WithDisplayName(b => "test");
// Assert
var endpoint = builder.Build();
Assert.Equal("test", endpoint.DisplayName);
}
[Fact]
public void WithMetadata_AddsMetadata()
{
// Arrange
var builder = CreateBuilder();
// Act
builder.WithMetadata("test", new HostAttribute("www.example.com", "example.com"));
// Assert
var endpoint = builder.Build();
var hosts = endpoint.Metadata.GetMetadata<IHostMetadata>();
Assert.NotNull(hosts);
Assert.Equal(new[] { "www.example.com", "example.com" }, hosts.Hosts);
var @string = endpoint.Metadata.GetMetadata<string>();
Assert.Equal("test", @string);
}
private DefaultEndpointConventionBuilder CreateBuilder()
{
return new DefaultEndpointConventionBuilder(new RouteEndpointBuilder(
TestConstants.EmptyRequestDelegate,
RoutePatternFactory.Parse("/test"),
order: 0));
}
}
}

View File

@ -24,10 +24,7 @@ namespace Microsoft.AspNetCore.Builder
.UseHello(greeter)
.Build();
return routes.Map(
pattern,
"Hello " + greeter,
pipeline);
return routes.Map(pattern, pipeline);
}
}
}

View File

@ -71,7 +71,6 @@ namespace RoutingSandbox
});
builder.MapGet(
"/graph",
"DFA Graph",
(httpContext) =>
{
using (var writer = new StreamWriter(httpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
@ -82,7 +81,7 @@ namespace RoutingSandbox
}
return Task.CompletedTask;
});
}).WithDisplayName("DFA Graph");
builder.MapGet("/attributes", HandlerWithAttributes);

View File

@ -24,10 +24,7 @@ namespace Microsoft.AspNetCore.Builder
.UseHello(greeter)
.Build();
return routes.Map(
template,
"Hello " + greeter,
pipeline);
return routes.Map(template, pipeline).WithDisplayName("Hello " + greeter);
}
}
}

View File

@ -108,8 +108,7 @@ namespace RoutingWebSite
response.ContentType = "text/plain";
return response.WriteAsync(
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithSingleAsteriskCatchAll", new { }));
},
new RouteNameMetadata(routeName: "WithSingleAsteriskCatchAll"));
}).WithMetadata(new RouteNameMetadata(routeName: "WithSingleAsteriskCatchAll"));
routes.MapGet(
"/WithDoubleAsteriskCatchAll/{**path}",
(httpContext) =>
@ -121,8 +120,7 @@ namespace RoutingWebSite
response.ContentType = "text/plain";
return response.WriteAsync(
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithDoubleAsteriskCatchAll", new { }));
},
new RouteNameMetadata(routeName: "WithDoubleAsteriskCatchAll"));
}).WithMetadata(new RouteNameMetadata(routeName: "WithDoubleAsteriskCatchAll"));
MapHostEndpoint(routes);
MapHostEndpoint(routes, "*.0.0.1");

View File

@ -38,8 +38,7 @@ namespace MvcSandbox
{
builder.MapGet(
requestDelegate: WriteEndpoints,
pattern: "/endpoints",
displayName: "Home");
pattern: "/endpoints").WithDisplayName("Home");
builder.MapControllerRoute(
name: "default",
@ -53,7 +52,6 @@ namespace MvcSandbox
builder.MapGet(
"/graph",
"DFA Graph",
(httpContext) =>
{
using (var writer = new StreamWriter(httpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
@ -64,7 +62,7 @@ namespace MvcSandbox
}
return Task.CompletedTask;
});
}).WithDisplayName("DFA Graph");
builder.MapControllers();
builder.MapRazorPages();