8

I'm building a console app to do some database work for me and want to set up different appsettings files to store the appropriate connection strings per environment. I have something this working in my Main function at the moment:

static void Main(string[] args)
{
            IConfiguration config = new ConfigurationBuilder()
              .AddJsonFile("appsettings.json", true, true)
              .Build();

            var dbconnection = config["db"];
}

But while this is working, it's just one global appsettings file. I'd like to be able to create different appsettings for each environment (e.g. appsettings.Dev.json, appsettings.Staging.json, etc.), but I can't figure out how to feed whatever selection I have in the configuration manager when I run the app to the addjsonfile string.

For some additional context, I'd like to feed this into my dbcontext later in the app if that affects anything.

Paul DeVito
  • 1,542
  • 3
  • 15
  • 38

3 Answers3

13

The other answers here were helpful, but I wanted to expand on exactly what I did for others that come across this.

The first thing you'll want to do is to go into your launch settings.json and add something like this:

{
  "profiles": {
    "DataMigration (Local)": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Local"
      }
    },
    "DataMigration (Dev)": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Dev"
      }
    }
  }
}

This will give you access to an environment variable depending on which profile you launch your project with (note the configuration manager has no impact here).

Then you can create different appsetting.json files. For example, I made an appsettings.Local.json and a appsettings.Dev.json file.

appsettings.Local.json

{
  "db": "connectionstringhere"
}

and

appsettings.Dev.json

{
  "db": "connectionstringhere"
}

Now, you can then access the environment variable that you run your app with like so:

static void Main(string[] args)
{
    var myEnv = System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
    IConfiguration config = new ConfigurationBuilder()
        .AddJsonFile($"appsettings.{myEnv}.json", false)
        .Build();

    var dbconnection = config["db"];
}

To take it a step further, instead of doing it here, I made by db context flexible like so:

public class ShoppingDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var myEnv = System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

        if(myEnv != null)
        {
            IConfiguration config = new ConfigurationBuilder()
                 .AddJsonFile($"appsettings.{myEnv}.json", false)
                 .Build();

            var sl = config[$"db"];
           optionsBuilder.UseSqlServer(sl);
        }
        else
        {
            // we are testing and want local for sure
            IConfiguration config = new ConfigurationBuilder()
                 .AddJsonFile($"appsettings.Local.json", false)
                 .Build();

            var sl = config[$"db"];
            optionsBuilder.UseSqlServer(sl);
        }
    }

    public DbSet<MyTable> MyTables { get; set; }
}
Paul DeVito
  • 1,542
  • 3
  • 15
  • 38
  • 2
    Upvoted for including default appsettings.Local.json if ASPNETCORE_ENVIRONMENT is unset – anon_dcs3spp Nov 08 '20 at 13:44
  • I'd add that the launchSettings .json file must be under Properties folder, ideally you can create it from Debug Properties UI in VS – mikus Sep 25 '22 at 14:03
5

You can have as many configuration files as you want just add a line of code to your configuration builder as below :

IConfiguration config = new ConfigurationBuilder()
          .AddJsonFile("appsettings.json", false)
          .AddJsonFile($"appsettings.{environmentName}.json", true)
          .Build();

You need also to configure your environement name for your application as shwon below :

enter image description here

sayah imad
  • 1,507
  • 3
  • 16
  • 24
3

That fact that you're building a console app is inconsequential: you'd handle this the same way an ASP.NET Core app does (which is actually just a console app too).

.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

Here, env is an instance of IHostingEnvironment, which is not applicable to your case here. However, the only purpose of it is to get as the value of the environment configuration value. That value can be set many ways, most typically via the ASPNETCORE_ENVIRONMENT environment variable. But, it could also be passed as a command-line argument. Since you're building a console app here, you can provide it however you like. In the end, you'll simply take the environment value and sub that into filename in the AddJsonFile call.

// get environment value from either `Environment.GetEnvironmentVariable` or by parsing command line arguments

.AddJsonFile($"appsettings.{myEnvironment}.json", optional: true, reloadOnChange: true);

You can also opt to do configuration in two rounds. In the first round, you add the environment variable and/or command line argument configuration providers, build that configuration source, and then use that to pull out the environment value for the second configuration setup, i.e. the one you're actually going to be using. That's a bit of overkill for environment variables alone, but if you want to provide the option of providing the value via command line arguments, all that manual parsing can be pain.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444