using Microsoft.Extensions.Options; namespace ECMJobRunner.WebCron.ProfileWorker; /// /// Extension methods for configuring ProfileWorker services in the DI container. /// public static class DependencyInjection { /// /// Registers ProfileWorker background service and related dependencies. /// /// The service collection to configure. /// Application configuration containing ProfileWorker settings. /// The configured service collection for method chaining. /// /// Registers the following services: /// /// - Configuration options from appsettings.json /// - Singleton background service (also registered as IHostedService) /// - Singleton cache for profile state /// - Scoped service for profile synchronization logic /// /// public static IServiceCollection AddProfileWorker(this IServiceCollection services, IConfiguration configuration) { // Configure ProfileWorker options from appsettings.json services.Configure( configuration.GetSection(ProfileWorkerOptions.SectionName)); // Validate options at startup services.AddSingleton, ProfileWorkerOptionsValidator>(); // Register ProfileWorker as both HostedService and singleton (for health check access) services.AddSingleton(); services.AddHostedService(sp => sp.GetRequiredService()); services.AddSingleton(); services.AddScoped(); return services; } } /// /// Validates configuration at application startup. /// Ensures IntervalMS is within acceptable bounds to prevent misconfiguration. /// internal class ProfileWorkerOptionsValidator : IValidateOptions { /// /// Validates the ProfileWorker options. /// /// The name of the options instance (not used). /// The options to validate. /// /// if valid, /// or with error message if invalid. /// /// /// Validation rules: /// /// IntervalMS must be greater than 0 /// IntervalMS should be at least 100ms to avoid excessive CPU usage /// /// public ValidateOptionsResult Validate(string? name, ProfileWorkerOptions options) { if (options.IntervalMS <= 0) { return ValidateOptionsResult.Fail("ProfileWorker:IntervalMs must be greater than 0"); } if (options.IntervalMS < 100) { return ValidateOptionsResult.Fail("ProfileWorker:IntervalMs should be at least 100ms to avoid excessive CPU usage"); } return ValidateOptionsResult.Success; } }