.NET Core allows to lazily read settings from configuration file, de-serialize it to a POCO and register that POCO in built-in DI container with one line of code:
Deserialize options with configuration.Get or configuration.Bind call and register a POCO in DI container explicitly as singleton:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingletonFromFile(Configuration.GetSection("MySection"));
}
//...
public static IServiceCollection AddSingletonFromFile(
this IServiceCollection services,
IConfiguration configuration)
where TOptions : class, new()
{
//POCO is created with actual values
TOptions options = configuration.Get();
services.AddSingleton(options);
return services;
}
UPD: thanks to @NPNelson for .Get hint.
Then IOptions resolving is no longer needed, and the class dependencies become clear:
public HomeController(MyOptions options)
{
_options = options;
}
FYI: reading from an external service (database etc.) is also possible this way:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransientFromService(reader => reader.GetOptions());
}
//...
public static void AddTransientFromService(
this IServiceCollection services,
Func getOptions)
where TReader : class
where TOptions : class
{
services.AddTransient(provider => getOptions(provider.GetService()));
}
Remarks:
reloadOnChange option setup: .AddJsonFile("appsettings.json", false, reloadOnChange: true));If you really need the file reload and you still don't want to use IOptions, consider a transient resolving. Of course, per-request resolving can lead to the significant perfomance decrease.