When using environment-specific appsettings.json files, is there a way, per-setting, to replace, and not add to?

570 Views Asked by At

I discovered that when setting up a console application using the .NET Generic Host, and using multiple appsettings.json files, the contents of latter files overwrite the contents of earlier files (registration-wise) in-memory, but they don't replace it.

Let me explain, I'll post the code that reproduces this below but first the two json files:

  • appsettings.json, loaded first

    {
        "Folders": [
            "main-1",
            "main-2"
        ]
    }
    
  • appsettings.debug.json, loaded second

    {
        "Folders": [
            "debug-1"
        ]
    }
    

When loading this into an options object, I would expect that the debug setting takes precedence, and it does, sort of, but it simply replaces the first element of the main configuration file.

Let me rephrase that. I load the configuration files into this class:

internal class Options
{
    public List<string> Folders { get; } = new List<string>();
}

When both files are added, and the debug file is added last, what I want is for the list property above to only contain "debug-1".

Instead, it contains "debug-1", "main-2", so only the first element was overwritten, the second was not.

While I could understand this for a dictionary, only replacing the keys I actually specified, for an array it seems a bit odd (to me).

Here's the code:

using System;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;

namespace ConsoleApp3
{
    class Program
    {
        static void Main()
        {
            var builder = new ConfigurationBuilder();
            builder.AddJsonFile("appsettings.json");
            builder.AddJsonFile("appsettings.debug.json");

            var configuration = builder.Build();
            var options = configuration.Get<Options>();

            foreach (var folder in options.Folders)
                Console.WriteLine(folder);
        }
    }

    internal class Options
    {
        public List<string> Folders { get; } = new List<string>();
    }
}

The output of this program is this:

debug-1
main-2

I would like for it to only contain "debug-1". Can I specify something when loading the configuration files that would make it behave like this?

This is a .NET Core 2.1 console application, I had to add the following packages:

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.Configuration.Binder
0

There are 0 best solutions below