// 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.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; namespace Microsoft.AspNetCore.Routing.Matching { internal class DataSourceDependentMatcher : Matcher { private readonly Func _matcherBuilderFactory; private readonly DataSourceDependentCache _cache; public DataSourceDependentMatcher( EndpointDataSource dataSource, Func matcherBuilderFactory) { _matcherBuilderFactory = matcherBuilderFactory; _cache = new DataSourceDependentCache(dataSource, CreateMatcher); _cache.EnsureInitialized(); } // Used in tests internal Matcher CurrentMatcher => _cache.Value; public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature) { return CurrentMatcher.MatchAsync(httpContext, feature); } private Matcher CreateMatcher(IReadOnlyList endpoints) { var builder = _matcherBuilderFactory(); for (var i = 0; i < endpoints.Count; i++) { // By design we only look at RouteEndpoint here. It's possible to // register other endpoint types, which are non-routable, and it's // ok that we won't route to them. if (endpoints[i] is RouteEndpoint endpoint && endpoint.Metadata.GetMetadata() == null) { builder.AddEndpoint(endpoint); } } return builder.Build(); } } }