In this lesson, you will learn how to leverage the IOptions<T> pattern to inject strongly-typed configuration settings into your background workers, ensuring your services remain decoupled from raw configuration files.
When building background services, you often need settings like polling intervals, API endpoints, or retry limits. While you could manually read from IConfiguration, doing so directly inside your worker is brittle and makes testing difficult. Instead, we use the Options pattern to bind a POCO (Plain Old CLR Object) to a configuration section and inject it via Dependency Injection.
Setting Up the Options
First, define a class that represents your settings:
public class WorkerOptions
{
public const string SectionName = "WorkerSettings";
public int PollingIntervalSeconds { get; set; } = 30;
public string TargetEndpoint { get; set; } = string.Empty;
}
Injecting into the Worker
In your Program.cs or Startup.cs, register the configuration in the DI container:
builder.Services.Configure<WorkerOptions>(builder.Configuration.GetSection(WorkerOptions.SectionName));
Now, inject IOptions<WorkerOptions> into your BackgroundService constructor. By using IOptions, you gain access to the configuration values without needing to know where they originated:
public class MyWorker : BackgroundService
{
private readonly WorkerOptions _options;
public MyWorker(IOptions<WorkerOptions> options)
{
_options = options.Value;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
// Use _options.PollingIntervalSeconds here
await Task.Delay(TimeSpan.FromSeconds(_options.PollingIntervalSeconds), stoppingToken);
}
}
}
Why use IOptions?
Using IOptions<T> provides several benefits over direct configuration access:
- Strong Typing: You get compile-time safety and IDE support, avoiding magic strings like
configuration["WorkerSettings:Interval"]. - Encapsulation: Your service doesn't need to know about the structure of your
appsettings.json, only the object model it expects. - Change Tracking: If you transition to
IOptionsSnapshot<T>later, your service can react to configuration changes at runtime without restarting the process.
Key Takeaway: Use the IOptions<T> pattern to inject strongly-typed settings into your background services, promoting cleaner code, easier testing, and clear separation between service logic and configuration data.