OK so I have it working now :) Because we use octopus deploy we don't want multiple config files so we just have the one appsettings.Release.json file which gets the values substituted base on the environment being deployed too.
Below is the main function code.
public static class Function
{
// Format in a CRON Expression e.g. {second} {minute} {hour} {day} {month} {day-of-week}
// https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer
// [TimerTrigger("0 59 23 * * *") = 11:59pm
[FunctionName("Function")]
public static void Run([TimerTrigger("0 59 23 * * *")]TimerInfo myTimer, ILogger log)
{
// If running in debug then we dont want to load the appsettings.json file, this has its variables substituted in octopus
// Running locally will use the local.settings.json file instead
#if DEBUG
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
#else
IConfiguration config = Utils.GetSettingsFromReleaseFile();
#endif
// Initialise dependency injections
var serviceProvider = Bootstrap.ConfigureServices(log4Net, config);
var retryCount = Convert.ToInt32(config["RetryCount"]);
int count = 0;
while (count < retryCount)
{
count++;
try
{
var business = serviceProvider.GetService<IBusiness>();
business.UpdateStatusAndLiability();
return;
}
catch (Exception e)
{
// Log your error
}
}
}
}
The Utils.cs file looks as follows
public static class Utils
{
public static string LoadSettingsFromFile(string environmentName)
{
var executableLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// We need to go back up one level as the appseetings.Release.json file is not put in the bin directory
var actualPathToConfig = Path.Combine(executableLocation, $"..\\appsettings.{environmentName}.json");
using (StreamReader reader = new StreamReader(actualPathToConfig))
{
return reader.ReadToEnd();
}
}
public static IConfiguration GetSettingsFromReleaseFile()
{
var json = Utils.LoadSettingsFromFile("Release");
var memoryFileProvider = new InMemoryFileProvider(json);
var config = new ConfigurationBuilder()
.AddJsonFile(memoryFileProvider, "appsettings.json", false, false)
.Build();
return config;
}
}
The appsettings.Release.json is set as Content and Copy Always in visual studio. It looks like this
{
"RetryCount": "#{WagonStatusAndLiabilityRetryCount}",
"RetryWaitInSeconds": "#{WagonStatusAndLiabilityRetryWaitInSeconds}",
"DefaultConnection": "#{YourConnectionString}"
}
Actually I believe you could have an appsettings.config file there already and skip the appsettings.Release.json file, but this is working and you can do what you want with it now.