Search code examples
c#asp.net-coreminimal-apis

Get AppSettings from Azure AppConfiguration before web application build


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?


Solution

  • 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.