diff --git a/src/Microsoft.AspNetCore.Routing/Matching/CandidateSet.cs b/src/Microsoft.AspNetCore.Routing/Matching/CandidateSet.cs
index dc51752923..be134bf6ce 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/CandidateSet.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/CandidateSet.cs
@@ -6,6 +6,11 @@ using System.Runtime.CompilerServices;
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// Represents a set of candidates that have been matched
+ /// by the routing system. Used by implementations of
+ /// and .
+ ///
public sealed class CandidateSet
{
// We inline storage for 4 candidates here to avoid allocations in common
@@ -18,8 +23,18 @@ namespace Microsoft.AspNetCore.Routing.Matching
private CandidateState[] _additionalCandidates;
- // Provided to make testing possible/easy for someone implementing
- // an EndpointSelector.
+ ///
+ ///
+ /// Initializes a new instances of the candidate set structure with the provided list of endpoints
+ /// and associated scores.
+ ///
+ ///
+ /// The constructor is provided to enable unit tests of implementations of
+ /// and .
+ ///
+ ///
+ /// The list of endpoints, sorted in descending priority order.
+ /// The list of endpoint scores. .
public CandidateSet(MatcherEndpoint[] endpoints, int[] scores)
{
Count = endpoints.Length;
@@ -112,12 +127,25 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
}
+ ///
+ /// Gets the count of candidates in the set.
+ ///
public int Count { get; }
- // Note that this is a ref-return because of both mutability and performance.
- // We don't want to copy these fat structs if it can be avoided.
+ ///
+ /// Gets the associated with the candidate
+ /// at .
+ ///
+ /// The candidate index.
+ ///
+ /// A reference to the . The result is returned by reference
+ /// and intended to be mutated.
+ ///
public ref CandidateState this[int index]
{
+ // Note that this is a ref-return because of both mutability and performance.
+ // We don't want to copy these fat structs if it can be avoided.
+
// PERF: Force inlining
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/CandidateState.cs b/src/Microsoft.AspNetCore.Routing/Matching/CandidateState.cs
index 4cb525bfac..cf27c04c78 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/CandidateState.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/CandidateState.cs
@@ -3,6 +3,9 @@
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// The mutable state associated with a candidate in a .
+ ///
public struct CandidateState
{
internal CandidateState(MatcherEndpoint endpoint, int score)
@@ -14,12 +17,39 @@ namespace Microsoft.AspNetCore.Routing.Matching
Values = null;
}
+ ///
+ /// Gets the .
+ ///
public MatcherEndpoint Endpoint { get; }
+ ///
+ /// Gets the score of the within the current
+ /// .
+ ///
+ ///
+ ///
+ /// Candidates within a set are ordered in priority order and then assigned a
+ /// sequential score value based on that ordering. Candiates with the same
+ /// score are considered to have equal priority.
+ ///
+ ///
+ /// The score values are used in the to determine
+ /// whether a set of matching candidates is an ambiguous match.
+ ///
+ ///
public int Score { get; }
+ ///
+ /// Gets or sets a value which indicates where the is considered
+ /// a valid candiate for the current request. Set this value to false to exclude an
+ /// from consideration.
+ ///
public bool IsValidCandidate { get; set; }
+ ///
+ /// Gets or sets the associated with the
+ /// and the current request.
+ ///
public RouteValueDictionary Values { get; set; }
}
}
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/EndpointMetadataComparer.cs b/src/Microsoft.AspNetCore.Routing/Matching/EndpointMetadataComparer.cs
index 6c617f5d03..b2a7b9ec00 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/EndpointMetadataComparer.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/EndpointMetadataComparer.cs
@@ -6,10 +6,30 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// A base class for implementations that use
+ /// a specific type of metadata from for comparison.
+ /// Useful for implementing .
+ ///
+ ///
+ /// The type of metadata to compare. Typically this is a type of metadata related
+ /// to the application concern being handled.
+ ///
public abstract class EndpointMetadataComparer : IComparer where TMetadata : class
{
public static readonly EndpointMetadataComparer Default = new DefaultComparer();
+ ///
+ /// Compares two objects and returns a value indicating whether one is less than, equal to,
+ /// or greater than the other.
+ ///
+ /// The first object to compare.
+ /// The second object to compare.
+ ///
+ /// An implementation of this method must return a value less than zero if
+ /// x is less than y, zero if x is equal to y, or a value greater than zero if x is
+ /// greater than y.
+ ///
public int Compare(Endpoint x, Endpoint y)
{
if (x == null)
@@ -25,11 +45,32 @@ namespace Microsoft.AspNetCore.Routing.Matching
return CompareMetadata(GetMetadata(x), GetMetadata(y));
}
+ ///
+ /// Gets the metadata of type from the provided endpoint.
+ ///
+ /// The .
+ /// The instance or null.
protected virtual TMetadata GetMetadata(Endpoint endpoint)
{
return endpoint.Metadata.GetMetadata();
}
+ ///
+ /// Compares two instances.
+ ///
+ /// The first object to compare.
+ /// The second object to compare.
+ ///
+ /// An implementation of this method must return a value less than zero if
+ /// x is less than y, zero if x is equal to y, or a value greater than zero if x is
+ /// greater than y.
+ ///
+ ///
+ /// The base-class implementation of this method will compare metadata based on whether
+ /// or not they are null. The effect of this is that when endpoints are being
+ /// compared, the endpoint that defines an instance of
+ /// will be considered higher priority.
+ ///
protected virtual int CompareMetadata(TMetadata x, TMetadata y)
{
// The default policy is that if x endpoint defines TMetadata, and
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/EndpointSelector.cs b/src/Microsoft.AspNetCore.Routing/Matching/EndpointSelector.cs
index 0af172bdca..436c3df6f5 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/EndpointSelector.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/EndpointSelector.cs
@@ -6,8 +6,25 @@ using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// A service that is responsible for the final selection
+ /// decision. To use a custom register an implementation
+ /// of in the dependency injection container as a singleton.
+ ///
public abstract class EndpointSelector
{
+ ///
+ /// Asynchronously selects an from the .
+ ///
+ /// The associated with the current request.
+ /// The associated with the current request.
+ /// The .
+ /// A that completes asynchronously once endpoint selection is complete.
+ ///
+ /// An should assign the ,
+ /// , and properties
+ /// once an endpoint is selected.
+ ///
public abstract Task SelectAsync(
HttpContext httpContext,
IEndpointFeature feature,
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs b/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs
index 9968395b29..0be502b1a2 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/HttpMethodMatcherPolicy.cs
@@ -12,6 +12,10 @@ using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// An that implements filtering and selection by
+ /// the HTTP method of a request.
+ ///
public sealed class HttpMethodMatcherPolicy : MatcherPolicy, IEndpointComparerPolicy, INodeBuilderPolicy
{
// Used in tests
@@ -25,12 +29,23 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Used in tests
internal const string AnyMethod = "*";
+ ///
+ /// For framework use only.
+ ///
public IComparer Comparer => new HttpMethodMetadataEndpointComparer();
// The order value is chosen to be less than 0, so that it comes before naively
// written policies.
+ ///
+ /// For framework use only.
+ ///
public override int Order => -1000;
+ ///
+ /// For framework use only.
+ ///
+ ///
+ ///
public bool AppliesToNode(IReadOnlyList endpoints)
{
if (endpoints == null)
@@ -49,6 +64,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
return false;
}
+ ///
+ /// For framework use only.
+ ///
+ ///
+ ///
public IReadOnlyList GetEdges(IReadOnlyList endpoints)
{
// The algorithm here is designed to be preserve the order of the endpoints
@@ -180,6 +200,12 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
}
+ ///
+ /// For framework use only.
+ ///
+ ///
+ ///
+ ///
public PolicyJumpTable BuildJumpTable(int exitDestination, IReadOnlyList edges)
{
var destinations = new Dictionary(StringComparer.OrdinalIgnoreCase);
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/IEndpointComparerPolicy.cs b/src/Microsoft.AspNetCore.Routing/Matching/IEndpointComparerPolicy.cs
index 9c187a6fec..a1010c181c 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/IEndpointComparerPolicy.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/IEndpointComparerPolicy.cs
@@ -5,8 +5,30 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// A interface that can be implemented to sort
+ /// endpoints. Implementations of must
+ /// inherit from and should be registered in
+ /// the dependency injection container as singleton services of type .
+ ///
+ ///
+ ///
+ /// Candidates in a are sorted based on their priority. Defining
+ /// a adds an additional criterion to the sorting
+ /// operation used to order candidates.
+ ///
+ ///
+ /// As an example, the implementation of implements
+ /// to ensure that endpoints matching specific HTTP
+ /// methods are sorted with a higher priority than endpoints without a specific HTTP method
+ /// requirement.
+ ///
+ ///
public interface IEndpointComparerPolicy
{
+ ///
+ /// Gets an that will be used to sort the endpoints.
+ ///
IComparer Comparer { get; }
}
}
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/IEndpointSelectorPolicy.cs b/src/Microsoft.AspNetCore.Routing/Matching/IEndpointSelectorPolicy.cs
index 63fe7dd8fd..7dfd04b7bd 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/IEndpointSelectorPolicy.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/IEndpointSelectorPolicy.cs
@@ -5,8 +5,26 @@ using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// A interface that can implemented to filter endpoints
+ /// in a . Implementations of must
+ /// inherit from and should be registered in
+ /// the dependency injection container as singleton services of type .
+ ///
public interface IEndpointSelectorPolicy
{
+ ///
+ /// Applies the policy to the .
+ ///
+ ///
+ /// The associated with the current request.
+ ///
+ /// The .
+ ///
+ /// Implementations of should implement this method
+ /// and filter the set of candidates in the by setting
+ /// to false where desired.
+ ///
void Apply(HttpContext httpContext, CandidateSet candidates);
}
}
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/MatcherEndpoint.cs b/src/Microsoft.AspNetCore.Routing/Matching/MatcherEndpoint.cs
index 194fb0dc3d..ff5067cb81 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/MatcherEndpoint.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/MatcherEndpoint.cs
@@ -9,6 +9,9 @@ using Microsoft.AspNetCore.Routing.Patterns;
namespace Microsoft.AspNetCore.Routing.Matching
{
+ ///
+ /// Represents an that can be used in URL matching or URL generation.
+ ///
public sealed class MatcherEndpoint : Endpoint
{
internal static readonly Func EmptyInvoker = (next) =>
@@ -16,6 +19,16 @@ namespace Microsoft.AspNetCore.Routing.Matching
return (context) => Task.CompletedTask;
};
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The delegate to invoke to create a .
+ /// The to use in URL matching.
+ /// The order assigned to the endpoint.
+ ///
+ /// The or metadata associated with the endpoint.
+ ///
+ /// The informational display name of the endpoint.
public MatcherEndpoint(
Func invoker,
RoutePattern routePattern,
@@ -39,10 +52,23 @@ namespace Microsoft.AspNetCore.Routing.Matching
Order = order;
}
+ ///
+ /// Gets the invoker. The invoker is a delegate used to create a .
+ ///
public Func Invoker { get; }
+ ///
+ /// Gets the order value of endpoint.
+ ///
+ ///
+ /// The order value provides absolute control over the priority
+ /// of an endpoint. Endpoints with a lower numeric value of order have higher priority.
+ ///
public int Order { get; }
+ ///
+ /// Gets the associated with the endpoint.
+ ///
public RoutePattern RoutePattern { get; }
}
}
diff --git a/src/Microsoft.AspNetCore.Routing/Matching/MatcherPolicy.cs b/src/Microsoft.AspNetCore.Routing/Matching/MatcherPolicy.cs
index 92d715c936..05a654efd9 100644
--- a/src/Microsoft.AspNetCore.Routing/Matching/MatcherPolicy.cs
+++ b/src/Microsoft.AspNetCore.Routing/Matching/MatcherPolicy.cs
@@ -1,10 +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 Microsoft.AspNetCore.Routing.Matching;
+
namespace Microsoft.AspNetCore.Routing
{
+ ///
+ /// Defines a policy that applies behaviors to the URL matcher. Implementations
+ /// of and related interfaces must be registered
+ /// in the dependency injection container as singleton services of type
+ /// .
+ ///
+ ///
+ /// implementations can implement the following
+ /// interfaces , ,
+ /// and .
+ ///
public abstract class MatcherPolicy
{
+ ///
+ /// Gets a value that determines the order the should
+ /// be applied. Policies are applied in ascending numeric value of the
+ /// property.
+ ///
public abstract int Order { get; }
}
}