Daniel Gimenez
Daniel Gimenez

Reputation: 20599

Upgrading to WebJobs SDK 3.0 has broken overridden configuration in appsettings

I migrate a WebJobs project to 3.0 and I've run into a peculiar issue. My project has an appsettings.json and various appsettings.environment.json files.

When running under any environment, instead of the environment settings overriding the base settings, the reverse is occurring: When any settings exist in the base settings and environment settings, the base settings is used.

I've tried variations of using HostBuilder.ConfigureAppConfiguration() and HostBuilder.ConfigureHostConfiguration() and in each case I notice something peculiar when I look at hostInstance.Configuration.Providers: There are always three instances of JsonConfigurationProvider, with either two inside ChainedConfigurationProvider when configuring host or just as part of the main provider array when using application. The first instance is always my base, the second is always the environment and the third is always the base again.

So I believe my problem is that this third JsonConfigurationProvider is getting added, but I don't know how it is getting added.

Here is the relevant code from my WebJob:

var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
        ?? Environment.GetEnvironmentVariable("ENV")
        ?? "development";

var builder = new HostBuilder()
    .UseEnvironment(envName)
    .ConfigureAppConfiguration(b =>
    {
        b.SetBasePath(Environment.CurrentDirectory)
            .AddCommandLine(args, StartupSettings.SwitchMapping)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{envName}.json", optional: false, reloadOnChange: true)
            .AddEnvironmentVariables();
    });

builder.ConfigureWebJobs((context, b) =>
{
    b.AddAzureStorageCoreServices();
    b.AddAzureStorage();
    b.AddTimers();
});
builder.ConfigureLogging((context, b) =>
{
    if (false && context.HostingEnvironment.IsDevelopment())
    {
        b.SetMinimumLevel(LogLevel.Debug);
    }
    else
    {
        b.SetMinimumLevel(LogLevel.Information);
        b.AddFilter("Microsoft.EntityFrameworkCore.Database.Command", LogLevel.Warning);
    }
    b.AddConsole();

    var applicationInsightsKey = context.Configuration.GetValue<string>("ApplicationInsights:InstrumentationKey");
    b.AddApplicationInsights(o => o.InstrumentationKey = applicationInsightsKey);
})
.UseConsoleLifetime();

builder.ConfigureServices((context, services) =>
{
    /*...*/
});

return builder.Build();

Upvotes: 1

Views: 476

Answers (1)

Daniel Gimenez
Daniel Gimenez

Reputation: 20599

Just figured it out.

The extension method for ConfigureWebJobs() calls ConfigureAppConfiguration() and automatically adds appsettings. Since I was calling it after calling ConfigureAppConfiguration() that was the reason the last appsettings.json was the base one.

Code from WebJobsHostBuilderExtensions.ConfigureWebJobs:

builder.ConfigureAppConfiguration(config =>
{
   config.AddJsonFile("appsettings.json", optional: true);
   config.AddEnvironmentVariables();
});

The worst part is that these seems so superfluous.

Upvotes: 4

Related Questions