|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Swaggatherer;
internal static class Template
{
public static string Execute(IReadOnlyList<RouteEntry> entries)
{
var controllerCount = 0;
var templatesVisited = new Dictionary<string, (int ControllerIndex, int ActionIndex)>(
StringComparer.OrdinalIgnoreCase);
var setupEndpointsLines = new List<string>();
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<string>();
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 = HttpMethods.GetCanonicalizedValue({entries[i].Method});");
}
setupRequestsLines.Add($" Requests[{i}].Request.Path = \"{entries[i].RequestUrl}\";");
}
var setupMatcherLines = new List<string>();
for (var i = 0; i < entries.Count; i++)
{
setupMatcherLines.Add($" builder.AddEndpoint(Endpoints[{i}]);");
}
return string.Format(
CultureInfo.InvariantCulture,
@"
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
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<object>();
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);
}
}
|