My minimal web api use Azure App Configuration to store several configuration settings.
Now I need to get some values from that configurations before .Build() the web application and I can't find a way to obtain my settings other than use BuildServiceProvider.
var builder = WebApplication.CreateBuilder(args);
const string JSON = "json";
var appSettingsKey = CONSTANTS.APP.SETTINGS.APPSETTINGS.ToLower();
builder.Configuration.AddJsonFile($"{appSettingsKey}.{JSON}", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile($"{appSettingsKey}.{builder.Environment.EnvironmentName}.{JSON}", optional: true, reloadOnChange: true);
builder.Configuration.AddEnvironmentVariables();
builder.Services.Configure<Settings>(builder.Configuration.GetSection(CONSTANTS.APP.SETTINGS.EQUINOX_SETTINGS_PREFIX));
builder.Configuration.AddAzureAppConfiguration(options => options.Connect(builder.Configuration.GetConnectionString(CONSTANTS.APP.SETTINGS.APP_CONFIGURATION_CONNECTION_STRING))
.Select(CONSTANTS.APP.SETTINGS.EQUINOX_SETTINGS_KEY_FILTER, CONSTANTS.APP.SETTINGS.EQUINOX_SETTINGS_LABEL_FILTER)
.ConfigureRefresh(refresh => refresh.Register($"{CONSTANTS.APP.SETTINGS.EQUINOX_SETTINGS_PREFIX}:{CONSTANTS.APP.SETTINGS.SENTINEL_KEY}", refreshAll: true))
.UseFeatureFlags());
var buildServiceProvider = builder.Services.BuildServiceProvider();
var settings = (buildServiceProvider.GetRequiredService<IOptions<Settings>>() ?? null) ?? throw new InvalidOperationException();
builder.Host.UseSerilog((hostBuilderContext, services, configuration) =>
{
configuration.ConfigureLogging(CONSTANTS.CLUSTER.EQUINOX.ToUpper());
configuration.AddApplicationInsightsLogging(services, hostBuilderContext.Configuration, settings.Value);
});
builder.UseOrleans(settings);
builder.AddServices(settings);
var app = builder.Build();
Now I know that calling 'BuildServiceProvider' from application code results in an additional copy of singleton services, but since I need to register some services that need those settings, for example ApplicationInsights for Serilog, I don't know how to do it.
What is the right way to do it?
You can use ConfigurationBinder.Get
extension method, no need to build service provider. Something along these lines:
// after setting up all configuration sources
var section = builder.Configuration.GetSection(CONSTANTS.APP.SETTINGS.EQUINOX_SETTINGS_PREFIX);
var settings = section.Get<Settings>();
// use settings
P.S.
AFAIK the AddJsonFile
and AddEnvironmentVariables
are added by default for web apps so you should be able to skip it.