Recently a reader asked me how I typically manage settings when there is more than one developer assigned to a project. To answer that fast – I use environment variables. In this tutorial, I will show the best way to configure individual developer settings.

I’m sure you know about the hierarchial JSON-based settings handled in appsettings.json. They make up a great solution for configuring global settings for the application, but not when it comes to each individual developer.

If you are ready, then let’s get started configuring some settings. Please notice that I’m using Visual Studio 2022 for this guide, which is the reason why env. variables has been moved.

What is appsettings.json?

I will make a brief introduction to appsettings.json just to show the difference between that and environment variables. If you are a previously .NET developer, you for sure know <AppSettings> and luckily for you, ASP.NET Core has something similar.

Normally (if not using a template) we would create a new file named appsettings.json and place application settings inside that as JSON properties. The file is simply JSON and is fully tool supported in Visual Studio + Code. This gives us a great way to validate and pretty-print the file using a JSON formatter tool.

A typical normal auto-generated appsettings.json with a connection string would look like the following:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "localhost": "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;"
  }
}

As you can see I have added a ConnectionStrings object with a property named localhost having the value of Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;. At runtime we can get that value from the config with the below code:

IConfiguration config = ...;
var localhost = config["ConnectionStrings.localhost"]

It’s also possible to create a strongly typed object representing the ConnectionStrings JSON object. Start by creating a class and then Configure that as a service, as I have done below:

public class ConnectionStrings
{
    public string localhost { get; set; }
}

services.Configure<ConnectionStrings>(connectionStrings);

When calling the Configure method, we can utilize dependency injection to inject a ConnectionStrings object into our code.

This gives us a hard-coded connection string for our source code and that would end up in a source control system if you are using such things. If you want to, you can read about my favorite GIT commands here. Anyway – what if our code is dependent on a central database where each developer has their own account? Then we have a problem and we are also exposing the credentials for each user… that doesn’t sound good to my ears.

Configure individual developer settings using environment variables

Now that we have a good understanding of how appsettings.json is working and where its limitations are, let’s take a look at environment variables.

Fortunately for us, the application settings in ASP.NET Core go very well hand-in-hand with environment variables. You can click on Debug (top ribbon menu bar) and select <ProjectName> Debug Properties in the menu and see your environment variables in the “Launch Profiles” window.

environment variables visual studio 2022
Environment Variables in Visual Studio 2022

In Visual Studio 2019 this was normally located under Debug in the Properties window for the project and it was also a little easier for beginners to add new variables. Don’t be scared it is still easy to add more variables to a project, it’s just done in another way.

Add a new environment variable with the value of your personal connection string. It could be something like: ConnectionStrings.localhost=Server=myServerAddress;Database=myDataBase;User Id=christian;Password=someRandomPassword;. The new and updated environment variables field would now have the value of ASPNETCORE_ENVIRONMENT=Development,ConnectionStrings.localhost=Server/=myServerAddress;Database/=myDataBase;User Id/=christian;Password/=someRandomPassword;.

The variable is stored inside Properties/launchSettings.json and would in normal circumstances not be submitted with the version control tool. Let’s verify that our new variable was added to that file:

{
  "$schema": "https://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:4030",
      "sslPort": 44304
    }
  },
  "profiles": {
    "LocalizationAPI": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ConnectionStrings.localhost": "Server=myServerAddress;Database=myDataBase;User Id=christian;Password=someRandomPassword;"
      },
      "applicationUrl": "https://localhost:7013;http://localhost:5013",
      "dotnetRunMessages": true
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

If we take a look at line 18, we can see that the new property and value have been added to the profile. Great!

In .NET 6 we have to use the Environment.GetEnvironmentVariable() method to retrieve the value of an environment variable from the current process:

public static string? GetEnvironmentVariable (ConnectionStrings.localhost);

The above code will at runtime load the connection string from the env. variable and can be used where you need it. Please notice that it is made nullable (“?“) as it might return a null reference.

Multiple configuration files

If the environment variables are not a thing for you and you still want to push the developer settings to the source control, then you can make use of the flexibility in ASP.NET Core. It is actually possible to have a configuration file per developer machine with individual settings, like the one below:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "localhost": "Server=myServerAddress;Database=myDataBase;User Id=christian;Password=someRandomPassword;"
  }
}

For this to work dynamically you would have to name this file the same name as the developer computer name (not the developer – the machine name). It could be something like appsettings.LAPTOP-JR5F9JR.json and then add the following line of code to your Program.cs file just below the other services you already got.

builder.Configuration.AddJsonFile("appsettings.json", false, true);
builder.Configuration.AddJsonFile($"appsettings.{Environment.MachineName}.json", true, true);

What did we just do? In the code above we instruct ASP.NET core to read settings from appsettings.json and override it with the settings in appsettings.{Environment.MachineName}.json where {Environment.MachineName} is replaced at runtime with the actual name of the developer machine. By doing it this way, we can override the files per machine.

Summary

In this short guide/tutorial you learned to configure individual developer settings in a .NET 6 application. The solutions I just taught you are perfect when working with non-secure settings but I would not recommend you to put in connection strings like above. If you need individual connection strings with personal credentials I would recommend you to read my article about user secrets.

If you got any issues, questions, or suggestions, please let me know in the comments. Happy coding! 🙂