From 38f7094fb0595f3922cb3fc11954abaf646c58da Mon Sep 17 00:00:00 2001 From: XShine555 Date: Sun, 5 Jul 2026 04:36:46 +0200 Subject: [PATCH] refactor(di): add AddApplication entry point and generic AddValidatedOptions - Add Musify.Application.AddApplication(services, config) as the layer's DI entry point: registers Mediator, UploadIntentValidator and all app configs - Collapse the 5 near-identical AddXConfiguration methods into a single generic AddValidatedOptions(config, section) - Move UploadIntentValidator registration out of Infrastructure into the Application layer (fixes layering leak); Infra config binding now uses the generic helper - Api calls AddApplication; Worker uses AddValidatedOptions for its configs Build: 0 warnings, 0 errors. Co-Authored-By: Claude Opus 4.8 --- .../Extensions/ServiceCollectionExtensions.cs | 9 +-- .../ApplicationDependencyInjection.cs | 24 +++++++ .../ConfigurationDependencyInjection.cs | 66 +++++-------------- .../Services/ServicesDependencyInjection.cs | 11 +--- backend/Musify.Worker/Program.cs | 6 +- 5 files changed, 47 insertions(+), 69 deletions(-) create mode 100644 backend/Musify.Application/ApplicationDependencyInjection.cs diff --git a/backend/Musify.Api/Extensions/ServiceCollectionExtensions.cs b/backend/Musify.Api/Extensions/ServiceCollectionExtensions.cs index e24e733..1ceb89e 100644 --- a/backend/Musify.Api/Extensions/ServiceCollectionExtensions.cs +++ b/backend/Musify.Api/Extensions/ServiceCollectionExtensions.cs @@ -1,7 +1,7 @@ using FluentValidation; using Musify.Infrastructure.MassTransit; using Musify.Infrastructure.Persistence; -using Musify.Application.Configuration; +using Musify.Application; using Musify.Infrastructure.Services; using Musify.Api.Authentication; using Musify.Api.DataTransferObjects.PlayLists; @@ -14,16 +14,11 @@ public static class ServiceCollectionExtensions { public static IServiceCollection AddApplicationServices(this IServiceCollection services, IConfiguration configuration) { + services.AddApplication(configuration); services.AddDatabase(configuration); - services.AddApplicationStorageConfiguration(configuration); - services.AddPlayListConfiguration(configuration); - services.AddTrackConfiguration(configuration); - services.AddStreamGatewayConfiguration(configuration); services.AddStorageService(configuration); services.AddStreamTicketService(configuration); - services.AddUploadIntentConfiguration(configuration); services.AddMassTransitClient(configuration); - services.AddMediator(); services.AddAuthenticationConfiguration(configuration); services.AddOpenApiConfiguration(); services.AddScalarConfiguration(); diff --git a/backend/Musify.Application/ApplicationDependencyInjection.cs b/backend/Musify.Application/ApplicationDependencyInjection.cs new file mode 100644 index 0000000..c34340c --- /dev/null +++ b/backend/Musify.Application/ApplicationDependencyInjection.cs @@ -0,0 +1,24 @@ +using Mediator; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Musify.Application.Configuration; +using Musify.Application.Services; + +namespace Musify.Application; + +public static class ApplicationDependencyInjection +{ + public static IServiceCollection AddApplication(this IServiceCollection services, IConfiguration configuration) + { + services.AddMediator(); + services.AddScoped(); + + services.AddValidatedOptions(configuration, ApplicationStorageConfiguration.SectionName); + services.AddValidatedOptions(configuration, PlayListConfiguration.SectionName); + services.AddValidatedOptions(configuration, TrackConfiguration.SectionName); + services.AddValidatedOptions(configuration, StreamGatewayConfiguration.SectionName); + services.AddValidatedOptions(configuration, UploadIntentConfiguration.SectionName); + + return services; + } +} diff --git a/backend/Musify.Application/Configuration/ConfigurationDependencyInjection.cs b/backend/Musify.Application/Configuration/ConfigurationDependencyInjection.cs index a4687af..4c341f3 100644 --- a/backend/Musify.Application/Configuration/ConfigurationDependencyInjection.cs +++ b/backend/Musify.Application/Configuration/ConfigurationDependencyInjection.cs @@ -1,57 +1,25 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -namespace Musify.Application.Configuration +namespace Musify.Application.Configuration; + +public static class ConfigurationDependencyInjection { - public static class ConfigurationDependencyInjection + public static IServiceCollection AddValidatedOptions( + this IServiceCollection services, + IConfiguration configuration, + string sectionName) + where T : class { - public static IServiceCollection AddApplicationStorageConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration) - { - serviceDescriptors - .AddOptionsWithValidateOnStart() - .Bind(configuration.GetRequiredSection(ApplicationStorageConfiguration.SectionName)) - .ValidateDataAnnotations(); - serviceDescriptors.AddSingleton(serviceProvider => - serviceProvider.GetRequiredService>().Value); + services + .AddOptionsWithValidateOnStart() + .Bind(configuration.GetRequiredSection(sectionName)) + .ValidateDataAnnotations(); - return serviceDescriptors; - } + services.AddSingleton(serviceProvider => + serviceProvider.GetRequiredService>().Value); - public static IServiceCollection AddPlayListConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration) - { - serviceDescriptors - .AddOptionsWithValidateOnStart() - .Bind(configuration.GetRequiredSection(PlayListConfiguration.SectionName)) - .ValidateDataAnnotations(); - serviceDescriptors.AddSingleton(serviceProvider => - serviceProvider.GetRequiredService>().Value); - - return serviceDescriptors; - } - - public static IServiceCollection AddTrackConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration) - { - serviceDescriptors - .AddOptionsWithValidateOnStart() - .Bind(configuration.GetRequiredSection(TrackConfiguration.SectionName)) - .ValidateDataAnnotations(); - serviceDescriptors.AddSingleton(serviceProvider => - serviceProvider.GetRequiredService>().Value); - - return serviceDescriptors; - } - - public static IServiceCollection AddStreamGatewayConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration) - { - serviceDescriptors - .AddOptionsWithValidateOnStart() - .Bind(configuration.GetRequiredSection(StreamGatewayConfiguration.SectionName)) - .ValidateDataAnnotations(); - serviceDescriptors.AddSingleton(serviceProvider => - serviceProvider.GetRequiredService>().Value); - - return serviceDescriptors; - } + return services; } -} \ No newline at end of file +} diff --git a/backend/Musify.Infrastructure/Services/ServicesDependencyInjection.cs b/backend/Musify.Infrastructure/Services/ServicesDependencyInjection.cs index 45df273..ab5ca1c 100644 --- a/backend/Musify.Infrastructure/Services/ServicesDependencyInjection.cs +++ b/backend/Musify.Infrastructure/Services/ServicesDependencyInjection.cs @@ -5,7 +5,6 @@ using Microsoft.Extensions.Options; using Musify.Application.Configuration; using Musify.Infrastructure.Configuration; using Musify.Infrastructure.Jobs; -using Musify.Application.Services; using Musify.Application.Contracts; namespace Musify.Infrastructure.Services @@ -46,15 +45,7 @@ namespace Musify.Infrastructure.Services public static IServiceCollection AddUploadIntentConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration) { - serviceDescriptors - .AddOptionsWithValidateOnStart() - .Bind(configuration.GetRequiredSection(UploadIntentConfiguration.SectionName)) - .ValidateDataAnnotations(); - - serviceDescriptors.AddSingleton(serviceProvider => - serviceProvider.GetRequiredService>().Value); - - serviceDescriptors.AddScoped(); + serviceDescriptors.AddValidatedOptions(configuration, UploadIntentConfiguration.SectionName); return serviceDescriptors; } diff --git a/backend/Musify.Worker/Program.cs b/backend/Musify.Worker/Program.cs index 90d42e0..1b96107 100644 --- a/backend/Musify.Worker/Program.cs +++ b/backend/Musify.Worker/Program.cs @@ -10,9 +10,9 @@ var configuration = builder.Configuration; var services = builder.Services; -services.AddApplicationStorageConfiguration(configuration); -services.AddPlayListConfiguration(configuration); -services.AddTrackConfiguration(configuration); +services.AddValidatedOptions(configuration, ApplicationStorageConfiguration.SectionName); +services.AddValidatedOptions(configuration, PlayListConfiguration.SectionName); +services.AddValidatedOptions(configuration, TrackConfiguration.SectionName); services.AddStorageService(configuration); services.AddAudioTranscoder(configuration); services.AddPictureService(configuration);