Files
vegasco/src/Vegasco.Server.Api/Common/DependencyInjectionExtensions.cs

171 lines
4.4 KiB
C#
Raw Normal View History

using Asp.Versioning;
using FluentValidation;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
2025-06-12 19:12:38 +02:00
using System.Diagnostics;
using System.Reflection;
using Vegasco.Server.Api.Authentication;
using Vegasco.Server.Api.Common;
using Vegasco.Server.Api.Persistence;
namespace Vegasco.Server.Api.Common;
public static class DependencyInjectionExtensions
{
/// <summary>
/// Adds all the Api related services to the Dependency Injection container.
/// </summary>
/// <param name="builder"></param>
public static void AddApiServices(this IHostApplicationBuilder builder)
{
2025-07-22 20:19:57 +02:00
builder.AddBuilderServices();
builder.Services
.AddMiscellaneousServices()
.AddCustomOpenApi()
.AddApiVersioning()
.AddAuthenticationAndAuthorization(builder.Environment);
builder.AddDbContext();
}
2025-07-22 20:19:57 +02:00
private static IHostApplicationBuilder AddBuilderServices(this IHostApplicationBuilder builder)
{
string? seqHost = builder.Configuration.GetConnectionString("seq");
if (!string.IsNullOrEmpty(seqHost))
{
builder.AddSeqEndpoint("seq");
}
2025-07-22 20:19:57 +02:00
return builder;
}
private static IServiceCollection AddMiscellaneousServices(this IServiceCollection services)
{
2025-06-13 19:39:37 +02:00
services.AddSingleton(() =>
2025-06-12 19:18:17 +02:00
{
2025-06-13 19:39:37 +02:00
string assemblyName = Assembly.GetExecutingAssembly()
.GetName()
.Name ?? "Vegasco.Server.Api";
2025-06-12 19:18:17 +02:00
return new ActivitySource(assemblyName);
});
2025-06-12 19:12:38 +02:00
services.AddResponseCompression();
services.AddValidatorsFromAssemblies(
[
typeof(IApiMarker).Assembly
], ServiceLifetime.Singleton);
services.AddHealthChecks();
2024-08-17 16:38:40 +02:00
services.AddHttpContextAccessor();
2024-08-24 13:43:43 +02:00
services.AddHostedService<ApplyMigrationsService>();
2025-06-13 19:39:37 +02:00
services.AddRequestLocalization(o =>
{
string[] cultures =
[
"en-US",
"en",
"de-DE",
"de"
];
2025-06-13 19:39:37 +02:00
o.SetDefaultCulture(cultures[0])
.AddSupportedCultures(cultures)
.AddSupportedUICultures(cultures);
});
2024-08-24 13:43:43 +02:00
return services;
}
private static IServiceCollection AddCustomOpenApi(this IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddOpenApi(o =>
2024-08-17 16:38:40 +02:00
{
o.CreateSchemaReferenceId = jsonTypeInfo =>
2024-08-17 16:38:40 +02:00
{
if (string.IsNullOrEmpty(jsonTypeInfo.Type.FullName))
2024-08-17 16:38:40 +02:00
{
return jsonTypeInfo.Type.Name;
2024-08-17 16:38:40 +02:00
}
string? fullClassName = jsonTypeInfo.Type.FullName;
2024-08-17 16:38:40 +02:00
if (!string.IsNullOrEmpty(jsonTypeInfo.Type.Namespace))
2024-08-17 16:38:40 +02:00
{
fullClassName = fullClassName
.Replace(jsonTypeInfo.Type.Namespace, "")
2024-08-17 16:38:40 +02:00
.TrimStart('.');
}
fullClassName = fullClassName.Replace('+', '_');
2024-08-17 16:38:40 +02:00
return fullClassName;
};
2024-08-17 16:38:40 +02:00
});
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 AddAuthenticationAndAuthorization(this IServiceCollection services, IHostEnvironment environment)
{
services.AddOptions<JwtOptions>()
.BindConfiguration(JwtOptions.SectionName)
.ValidateFluently()
.ValidateOnStart();
2025-06-24 19:28:55 +02:00
IOptions<JwtOptions> 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;
}
o.RequireHttpsMetadata = !jwtOptions.Value.AllowHttpMetadataUrl && !environment.IsDevelopment();
});
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 IHostApplicationBuilder AddDbContext(this IHostApplicationBuilder builder)
2024-08-17 16:38:40 +02:00
{
builder.AddNpgsqlDbContext<ApplicationDbContext>(AppHost.Shared.Constants.Database.Name);
return builder;
}
}