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;
}
}