TriggeringProfileJobCommand: - Add RecActionResult property to store ReC action execution results - Convert handler to primary constructor with ISender injection - Create ProfileHistory after successful job execution - Include detailed execution metrics in history (TotalActionCount, ActionExceptionCount, BatchId) - Add required using statements for ProfileHistories and ValueObjects ProfileWorkerOptionsValidator: - Fix XML documentation reference to ValidateOptionsResult.Fail(string)
82 lines
3.5 KiB
C#
82 lines
3.5 KiB
C#
using Microsoft.Extensions.Options;
|
|
|
|
namespace ECMJobRunner.WebCron.ProfileWorker;
|
|
|
|
/// <summary>
|
|
/// Extension methods for configuring ProfileWorker services in the DI container.
|
|
/// </summary>
|
|
public static class DependencyInjection
|
|
{
|
|
/// <summary>
|
|
/// Registers ProfileWorker background service and related dependencies.
|
|
/// </summary>
|
|
/// <param name="services">The service collection to configure.</param>
|
|
/// <param name="configuration">Application configuration containing ProfileWorker settings.</param>
|
|
/// <returns>The configured service collection for method chaining.</returns>
|
|
/// <remarks>
|
|
/// Registers the following services:
|
|
/// <list type="bullet">
|
|
/// <item><description><see cref="ProfileWorkerOptions"/> - Configuration options from appsettings.json</description></item>
|
|
/// <item><description><see cref="ProfileWorker"/> - Singleton background service (also registered as IHostedService)</description></item>
|
|
/// <item><description><see cref="ProfileCache"/> - Singleton cache for profile state</description></item>
|
|
/// <item><description><see cref="ProfileWork"/> - Scoped service for profile synchronization logic</description></item>
|
|
/// </list>
|
|
/// </remarks>
|
|
public static IServiceCollection AddProfileWorker(this IServiceCollection services, IConfiguration configuration)
|
|
{
|
|
// Configure ProfileWorker options from appsettings.json
|
|
services.Configure<ProfileWorkerOptions>(
|
|
configuration.GetSection(ProfileWorkerOptions.SectionName));
|
|
|
|
// Validate options at startup
|
|
services.AddSingleton<IValidateOptions<ProfileWorkerOptions>, ProfileWorkerOptionsValidator>();
|
|
|
|
// Register ProfileWorker as both HostedService and singleton (for health check access)
|
|
services.AddSingleton<ProfileWorker>();
|
|
services.AddHostedService(sp => sp.GetRequiredService<ProfileWorker>());
|
|
|
|
services.AddSingleton<ProfileCache>();
|
|
services.AddScoped<ProfileWork>();
|
|
|
|
return services;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates <see cref="ProfileWorkerOptions"/> configuration at application startup.
|
|
/// Ensures IntervalMS is within acceptable bounds to prevent misconfiguration.
|
|
/// </summary>
|
|
internal class ProfileWorkerOptionsValidator : IValidateOptions<ProfileWorkerOptions>
|
|
{
|
|
/// <summary>
|
|
/// Validates the ProfileWorker options.
|
|
/// </summary>
|
|
/// <param name="name">The name of the options instance (not used).</param>
|
|
/// <param name="options">The options to validate.</param>
|
|
/// <returns>
|
|
/// <see cref="ValidateOptionsResult.Success"/> if valid,
|
|
/// or <see cref="ValidateOptionsResult.Fail(string)"/> with error message if invalid.
|
|
/// </returns>
|
|
/// <remarks>
|
|
/// Validation rules:
|
|
/// <list type="bullet">
|
|
/// <item><description>IntervalMS must be greater than 0</description></item>
|
|
/// <item><description>IntervalMS should be at least 100ms to avoid excessive CPU usage</description></item>
|
|
/// </list>
|
|
/// </remarks>
|
|
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;
|
|
}
|
|
}
|