// 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 Swaggatherer { internal static class Template { public static string Execute(IReadOnlyList entries) { var controllerCount = 0; var templatesVisited = new Dictionary( StringComparer.OrdinalIgnoreCase); var setupEndpointsLines = new List(); for (var i = 0; i < entries.Count; i++) { var entry = entries[i]; // In attribute routing, same template is used for all actions within that controller. The following // simulates that where we only increment the controller count when a new endpoint for a new template // is being created. var template = entry.Template.TemplateText; if (!templatesVisited.TryGetValue(template, out var visitedTemplateInfo)) { controllerCount++; visitedTemplateInfo = (controllerCount, 0); } // Increment the action count within a controller template visitedTemplateInfo.ActionIndex++; templatesVisited[template] = visitedTemplateInfo; var controllerName = $"Controller{visitedTemplateInfo.ControllerIndex}"; var actionName = $"Action{visitedTemplateInfo.ActionIndex}"; var httpMethodText = entry.Method == null ? "httpMethod: null" : $"\"{entry.Method.ToUpperInvariant()}\""; setupEndpointsLines.Add($" Endpoints[{i}] = CreateEndpoint(\"{template}\", \"{controllerName}\", \"{actionName}\", {httpMethodText});"); } var setupRequestsLines = new List(); for (var i = 0; i < entries.Count; i++) { var entry = entries[i]; setupRequestsLines.Add($" Requests[{i}] = new DefaultHttpContext();"); setupRequestsLines.Add($" Requests[{i}].RequestServices = CreateServices();"); if (entry.Method != null) { setupRequestsLines.Add($" Requests[{i}].Request.Method = \"{entries[i].Method.ToUpperInvariant()}\";"); } setupRequestsLines.Add($" Requests[{i}].Request.Path = \"{entries[i].RequestUrl}\";"); } var setupMatcherLines = new List(); for (var i = 0; i < entries.Count; i++) { setupMatcherLines.Add($" builder.AddEndpoint(Endpoints[{i}]);"); } return string.Format(@" // 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.Http; using Microsoft.AspNetCore.Routing.Matching; namespace Microsoft.AspNetCore.Routing {{ // This code was generated by the Swaggatherer public partial class GeneratedBenchmark : EndpointRoutingBenchmarkBase {{ private protected const int EndpointCount = {3}; private protected void SetupEndpoints() {{ Endpoints = new RouteEndpoint[{3}]; {0} }} private protected void SetupRequests() {{ Requests = new HttpContext[{3}]; {1} }} private protected Matcher SetupMatcher(MatcherBuilder builder) {{ {2} return builder.Build(); }} private RouteEndpoint CreateEndpoint(string template, string controllerName, string actionName, string httpMethod) {{ var requiredValues = new {{ area = (string)null, controller = controllerName, action = actionName, page = (string)null }}; var defaults = new {{ area = (string)null, controller = controllerName, action = actionName, page = (string)null }}; var metadata = new List(); if (httpMethod != null) {{ metadata.Add(new HttpMethodMetadata(new string[] {{ httpMethod }})); }} return CreateEndpoint( template, defaults: defaults, requiredValues: requiredValues, metadata: metadata, routeName: controllerName); }} }} }}", string.Join(Environment.NewLine, setupEndpointsLines), string.Join(Environment.NewLine, setupRequestsLines), string.Join(Environment.NewLine, setupMatcherLines), entries.Count); } } }