1
votes

I want to use JSON configuration for my ASP.NET Core project, as documented here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.2

My configuration is called like so:

config
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{commandConfig["Site"]}.json", optional: true, reloadOnChange: true)
    .AddEnvironmentVariables();

In every appsettings.<site>.json, I could put this:

{
    "Site": "siteName1"
}

But that seems like a waste. What I want is to put this in appsettings.json:

{
    "Site": "$(Site)"
}

And have variable substitution replace $(Site) as appropriate.

Is anything like this possible?

2
What is $(Site) supposed to be substituted with?DavidG
@DavidG Yes, nothing in this syntax would allow that, so I'd want to do something at the end maybe, like .SubstituteVariables(context); and pass in Site in the context mapping.Scott Stafford
Well, let me rephrase where I was going... If you want to substitute with a particular known value, then you already know the value right?DavidG
Yes. But if I have 20 sites, managing 20 site config files with not only their Site settings, but also their log location (c:\logs\${Site}), their error email subject ([${Site}] Error Occurred), etc is painful. Better to specify those three once in the appsettings.json` exactly as I wrote in this comment than to manually substitute and maintain 20 site-specific files.Scott Stafford
Why do you have 20 config files? This doesn't make sense. You have one config file with replaceable values. For example config.EmailSubject.Replace("$(Site)", theNameOfThisSite)DavidG

2 Answers

3
votes

I created a library for that purpose it does exactly what you expect. See: https://github.com/molinch/ConfigurationSubstitutor You just need to register it as another configuration source.

For example if you have these three entries defined in the configuration:

  • Foo = {Bar1}{Bar2}{Bar1}
  • Bar1 = Barista
  • Bar2 = -Jean-

When requesting Foo from the configuration you will get: Barista-Jean-Barista

2
votes

I'm not sure sure if that's possible.

I would suggest using an environment variable:

var mySiteVariable = Environment.GetEnvironmentVariable("MySiteVariable");

config
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{mySiteVariable}.json", optional: true, reloadOnChange: true)
    .AddEnvironmentVariables();

UPDATE:

If you don't want to use another json file, you could use AddInMemoryCollection. Configs added later in the chain will overwrite variables from configs earlier in the chain.

config.SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddInMemoryCollection(new Dictionary<string, string>()
    {
        {"MyConfigVariable", "overwrite with this value"}
    });

There is no built-in way to do what you want. You could always read and parse the json file yourself if you really wanted to.