Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With WebApplicationFactory, add configuration source before Program.cs executes

I am using the new minimal .NET 6 hosting model, and I have an integration test.

Obviously Program.cs needs configuration values, so I want to use a custom appsettings.Test.json file. Docs say I can use ConfigureAppConfiguration but its delegate runs after Program, hence Program has no configuration. Here's the code added to the Minimal API Playground sample code:

internal class PlaygroundApplication : WebApplicationFactory<Program>
{
    private readonly string _environment;

    public PlaygroundApplication(string environment = "Development")
    {
        _environment = environment;
    }

    protected override IHost CreateHost(IHostBuilder builder)
    {
        builder.UseEnvironment(_environment);

        builder.ConfigureAppConfiguration(config =>
        {
            config.AddJsonFile(appSettings); // runs AFTER Program.cs
        });

        // Add mock/test services to the builder here
        builder.ConfigureServices(services =>
        {
        });

        return base.CreateHost(builder);
    }
}

How can I provide configuration to Program.cs?

var builder = WebApplication.CreateBuilder(args);

var keyVaultName = builder.Configuration["KeyVaultName"]; // null

builder.Configuration.AddAzureKeyVault(new SecretClient(
    new Uri($"https://{keyVaultName}.vault.azure.net/"),
    new DefaultAzureCredential()), new KeyVaultSecretManager());

I can set environment to Testand then in Program do:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json");

var keyVaultName = builder.Configuration["KeyVaultName"]; // has value from json

builder.Configuration.AddAzureKeyVault(new SecretClient(
    new Uri($"https://{keyVaultName}.vault.azure.net/"),
    new DefaultAzureCredential()), new KeyVaultSecretManager());

But is that correct?

like image 477
Kristoffer Jälén Avatar asked Nov 29 '25 06:11

Kristoffer Jälén


2 Answers

I found a workaround that I detail here: https://github.com/dotnet/aspnetcore/issues/37680#issuecomment-1032922656

If you override WebApplicationFactory<T>.CreateHost() and call IHostBuilder.ConfigureHostConfiguration() before calling base.CreateHost() the configuration you add will be visible inbetween WebApplication.CreateBuilder() and builder.Build(). From my testing it's visible in all the various places you'd look at the config (callbacks, etc.).

like image 172
Tom Winter Avatar answered Dec 02 '25 04:12

Tom Winter


This is currently not possible with the way the code is written unfortunately, according to https://github.com/dotnet/aspnetcore/issues/37680.

like image 36
Kristoffer Jälén Avatar answered Dec 02 '25 04:12

Kristoffer Jälén



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!