Files
vegasco/src/WebApi/Common/DependencyInjectionExtensions.cs

162 lines
4.1 KiB
C#
Raw Normal View History

using Asp.Versioning;
using FluentValidation;
using Microsoft.AspNetCore.Authentication.JwtBearer;
2024-08-17 16:38:40 +02:00
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using OpenTelemetry.Trace;
using System.Diagnostics;
using Vegasco.WebApi.Authentication;
using Vegasco.WebApi.Endpoints;
using Vegasco.WebApi.Endpoints.OpenApi;
2024-08-17 16:38:40 +02:00
using Vegasco.WebApi.Persistence;
namespace Vegasco.WebApi.Common;
public static class DependencyInjectionExtensions
{
/// <summary>
/// Adds all the WebApi related services to the Dependency Injection container.
/// </summary>
/// <param name="services"></param>
2024-08-17 16:38:40 +02:00
public static void AddWebApiServices(this IServiceCollection services, IConfiguration configuration)
{
services
.AddMiscellaneousServices()
.AddOpenApi()
.AddApiVersioning()
.AddOtel()
2024-08-17 16:38:40 +02:00
.AddAuthenticationAndAuthorization()
.AddDbContext(configuration);
}
private static IServiceCollection AddMiscellaneousServices(this IServiceCollection services)
{
services.AddResponseCompression();
services.AddValidatorsFromAssemblies(
[
typeof(IWebApiMarker).Assembly
], ServiceLifetime.Singleton);
services.AddHealthChecks();
services.AddEndpointsFromAssemblyContaining<IWebApiMarker>();
2024-08-17 16:38:40 +02:00
services.AddHttpContextAccessor();
return services;
}
private static IServiceCollection AddOpenApi(this IServiceCollection services)
{
services.ConfigureOptions<ConfigureSwaggerGenOptions>();
services.AddEndpointsApiExplorer();
2024-08-17 16:38:40 +02:00
services.AddSwaggerGen(o =>
{
o.CustomSchemaIds(type =>
{
if (string.IsNullOrEmpty(type.FullName))
{
return type.Name;
}
var fullClassName = type.FullName;
if (!string.IsNullOrEmpty(type.Namespace))
{
fullClassName = fullClassName
.Replace(type.Namespace, "")
.TrimStart('.');
}
return fullClassName;
});
});
return services;
}
private static IServiceCollection AddApiVersioning(this IServiceCollection services)
{
services.AddApiVersioning(o =>
{
o.DefaultApiVersion = new ApiVersion(1);
o.ApiVersionReader = new UrlSegmentApiVersionReader();
o.ReportApiVersions = true;
})
.AddApiExplorer(o =>
{
o.GroupNameFormat = "'v'V";
o.SubstituteApiVersionInUrl = true;
});
return services;
}
private static IServiceCollection AddOtel(this IServiceCollection services)
{
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
ActivitySource activitySource = new(Constants.AppOtelName);
services.AddSingleton(activitySource);
services.AddOpenTelemetry()
.WithTracing(t =>
{
t.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter()
.AddSource(activitySource.Name);
})
.WithMetrics();
return services;
}
private static IServiceCollection AddAuthenticationAndAuthorization(this IServiceCollection services)
{
services.AddOptions<JwtOptions>()
.BindConfiguration(JwtOptions.SectionName)
.ValidateFluently()
.ValidateOnStart();
var jwtOptions = services.BuildServiceProvider().GetRequiredService<IOptions<JwtOptions>>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
{
o.MetadataAddress = jwtOptions.Value.MetadataUrl;
o.TokenValidationParameters.ValidAudience = jwtOptions.Value.ValidAudience;
o.TokenValidationParameters.ValidateAudience = true;
if (!string.IsNullOrWhiteSpace(jwtOptions.Value.NameClaimType))
{
o.TokenValidationParameters.NameClaimType = jwtOptions.Value.NameClaimType;
}
});
services.AddAuthorizationBuilder()
.AddPolicy(Constants.Authorization.RequireAuthenticatedUserPolicy, p => p
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme));
2024-08-17 16:38:40 +02:00
services.AddScoped<UserAccessor>();
return services;
}
private static IServiceCollection AddDbContext(this IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<ApplicationDbContext>(o =>
{
o.UseNpgsql(configuration.GetConnectionString("Database"), c =>
{
c.EnableRetryOnFailure();
});
});
return services;
}
}