I didn't feel the need or desire to add a third party package when it seemed like it should be rather simple to implement. So I created a method to do just that.
private static string ParseSetting(string setting, IConfiguration configuration)
{
// Incoming: {Configuration:FolderOverrides:RouterPath}\\ProcessRoute
// Result: TheRoutersPath\\ProcessRoute
var result = configuration[setting] ?? string.Empty;
while (result.Contains('{'))
{
var lookup = result.Split('{', StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.Contains('}'))
.Select(x => x[..x.IndexOf('}')])
.FirstOrDefault();
if (lookup is not null)
{
var parsed = configuration[lookup];
if (parsed is not null)
{
var newResult = $"{result[..result.IndexOf('{')]}{parsed}{result[(result.IndexOf('}') + 1)..]}";
result = newResult;
}
else
{
// Cannot write to the log file yet as this file is setting it up at this point
throw new ArgumentOutOfRangeException(message: "Check the appSettings file for a missmatch of '{' and '}' and/or validate that the node between '{' and '}' exists.", null);
}
}
}
return result;
}
Then all you need to do is wherever you are dealing with your settings, inject the configuration into it and pass the injected configuration
object to the method.
In my example below I have created a singleton and have defaults in a constants file. Might be overkill for your scenario.
public ConfigurationSettings(IConfiguration configuration) {
...
Core.IncomingPath = ParseSetting("Configuration:Core:IncomingPath", configuration) ?? Constants.FolderStructure.Core.IncomingPath;
...
}
I didn't see the need for ${}
so I dropped the $
.
I have ensured that the following scenarios do work:
Single {Configuration:FolderOverrides:RouterPath}\\ProcessRoute
Multiple {Configuration:FolderOverrides:RouterPath}\\ProcessRoute\\{SomeOther:Node}
Together {Configuration:FolderOverrides:RouterPath}{SomeOther:Node}