using LiteCharms.Features.Abstractions; using LiteCharms.Features.Api; namespace LiteCharms.Features.Extensions; public static class Api { public const string Books = nameof(Books); public const string Payments = nameof(Payments); public static IApplicationBuilder MapEndpoints(this WebApplication app, IDictionary versionGroups) { var endpoints = app.Services.GetRequiredService>(); foreach (var endpoint in endpoints) { var versionAttributes = endpoint.GetType().GetCustomAttributes().ToList(); if (versionAttributes.Count != 0) { foreach (var attr in versionAttributes) if (versionGroups.TryGetValue(attr.MajorVersion, out var targetGroup)) endpoint.Map(targetGroup); } else endpoint.Map(app); } return app; } public static IServiceCollection AddEndpoints(this IServiceCollection services, Assembly assembly) { ServiceDescriptor[] discriptors = [.. assembly.DefinedTypes .Where(t => t is { IsInterface: false, IsAbstract: false }) .Where(t => t.IsAssignableTo(typeof(IEndpoint))) .Select(t => ServiceDescriptor.Transient(typeof(IEndpoint), t))]; services.TryAddEnumerable(discriptors); return services; } public static string ToEndpointName(this Type target, string? annotation = "") => $"{target.Name.Replace("Endpoint", string.Empty)}{annotation}".ToLower(CultureInfo.CurrentCulture); public static IServiceCollection AddApiServices(this IServiceCollection services, IConfiguration configuration) { services.AddHttpClient(); services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(1); options.ReportApiVersions = true; options.AssumeDefaultVersionWhenUnspecified = true; options.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(), new QueryStringApiVersionReader("version"), new QueryStringApiVersionReader("version"), new MediaTypeApiVersionReader("version")); }) .AddApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; }); var urls = configuration["ASPNETCORE_URLS"] ?? configuration["Urls"]; var healthUrl = "http://localhost:8080/health"; if (!string.IsNullOrWhiteSpace(urls)) { string firstUrl = urls.Split(';').FirstOrDefault(s => s.Contains("http://"))! .Replace("*", "localhost").Replace("+", "localhost"); healthUrl = $"{firstUrl.TrimEnd('/')}/health"; } services.AddHealthChecksUI(setup => { setup.SetNotifyUnHealthyOneTimeUntilChange(); setup.AddHealthCheckEndpoint("primary, heal", healthUrl); setup.SetHeaderText("Midrand Books"); }) .AddInMemoryStorage(); services.AddOutputCache(options => { options.AddBasePolicy(builder => builder.Cache()); options.DefaultExpirationTimeSpan = TimeSpan.FromSeconds(10); }); services.AddOpenApi(options => options.AddDocumentTransformer()); return services; } }