Newer
Older
Warehouse / src / WebApi / Swagger / SwaggerStartup.cs
@Derek Comartin Derek Comartin on 22 Aug 2023 2 KB Init
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using MyWarehouse.Infrastructure;
using MyWarehouse.WebApi.Swagger.Configuration;
using MyWarehouse.WebApi.Swagger.Filters;
using Swashbuckle.AspNetCore.SwaggerUI;

namespace MyWarehouse.WebApi.Swagger;

[ExcludeFromCodeCoverage]
internal static class SwaggerStartup
{
    public static void AddMySwagger(this IServiceCollection services, IConfiguration configuration)
    {
        var swaggerSettings = configuration.GetMyOptions<SwaggerSettings>();

        if (swaggerSettings.UseSwagger == false)
        {
            return;
        }

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = swaggerSettings.ApiName, Version = "v1" });

            // Add Login capability to Swagger UI.
            c.AddSecurityDefinition(SecuritySchemeNames.ApiLogin, new OpenApiSecurityScheme
            {
                Type = SecuritySchemeType.OAuth2,
                Flows = new OpenApiOAuthFlows
                {
                    Password = new OpenApiOAuthFlow()
                    {
                        TokenUrl = new Uri(swaggerSettings.LoginPath, UriKind.Relative)
                    }
                }
            });

            // Prevent SwaggerGen from throwing exception when multiple DTOs from different namespaces have the same type name.
            c.CustomSchemaIds(x =>
            {
                var lastNamespaceSection = x.Namespace![(x.Namespace!.LastIndexOf('.') + 1)..];
                var genericParameters = string.Join(',', (IEnumerable<Type>)x.GetGenericArguments());

                return $"{lastNamespaceSection}.{x.Name}{(string.IsNullOrEmpty(genericParameters) ? null : "<" + genericParameters + ">")}";
            });

            c.OperationFilter<SwaggerGroupFilter>();
            c.OperationFilter<SwaggerAuthorizeFilter>();
        });

        // Register options configurator for SwaggerUI; this will be picked up by UseSwaggerUI().
        services.AddTransient<IConfigureOptions<SwaggerUIOptions>, ConfigureSwaggerUIOptions>();
    }

    public static void UseMySwagger(this IApplicationBuilder app, IConfiguration configuration)
    {
        var swaggerSettings = configuration.GetMyOptions<SwaggerSettings>();

        if (swaggerSettings.UseSwagger == true)
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }
    }
}