Azure Function inject setting.{environment}.json

Photo from: https://wardpeter.com/trigger-azure-function-using-power-automate-part-3/

Configuration

The common way that we apply our custom setting under azure function via local.settings.json (for development) as example below:

``` local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"BYOB_TokenMap": "D:\\Temp",
"Uri": "http://xxxxxx/api/getxxxxx"
}
}

For the application side we could retrieve the user defined (Uri) using below code snippet:

[FunctionName("SaveXXXXXXDataToBlobJob")]
public void SaveXXXXXXDataToBlobJob([TimerTrigger("0 3 21 * * *")]TimerInfo myTimer, ILogger log)
{
var uri = Environment.GetEnvironmentVariable("Uri",
EnvironmentVariableTarget.Process);
}

But someone might curious that how if we could introduce injection setting.{environment}.json files according different environments just similar .NET console we got used to.

appsettings.json
|---- appsettings.debug.json
|---- appsettings.qas.json
|---- appsettings.release.json

Here were cues for handle these staff.

  • Override method ConfigureAppConfiguration and setup your setting json files.
``` Startup.cs
public class Startup : FunctionsStartup
{
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
if (builder == null) throw new ArgumentNullException(nameof(builder));
var context = builder.GetContext();
var env = Environment.GetEnvironmentVariable("NETCORE_ENVIRONMENT", EnvironmentVariableTarget.Process);
builder.ConfigurationBuilder
.SetBasePath(context.ApplicationRootPath)
.AddJsonFile($"{appsettings.json.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
}
}
  • Setup configure options to inject and bind class model into services via override method Configure.
``` Startup.cs
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services
.AddOptions<ConfigModel>()
.Configure<IOptions<ExecutionContextOptions>>((settings, exeContext) =>
builder.GetContext().Configuration.Bind(settings));
}}```appsetings.json
{
"Resource":
{"Uri": "http://xxxxxx/api/getxxxxx"}
}
```CofigModel.cs
public class ConfigModel
{
public Resource {get;set;}
}
public class Resource
{
public string Uri {get;set;}
}
  • After DI of configuration we could retrieve anywhere
```XxxService.cs
public class XxxService
{
private readonly ConfigModel _config;
public XxxService(
IOptions<ConfigModel> config)
{
_config = config.Value;
}

[FunctionName("SaveXXXXXXDataToBlobJob")]
public void SaveXXXXXXDataToBlobJob([TimerTrigger("0 3 21 * * *")]TimerInfo myTimer, ILogger log)
{
var uri = _config.Resource.Uri;
}}
  • By the way, we could also get our appsettting.json section and setup under method Configure.
``` Startup.cs
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
// optinal-1
var uri1 = builder.GetContext().Configuration.GetSection("Resource:Uri").Value;
// optinal-2
var uri2 = builder.Services.BuildServiceProvider().GetRequiredService<ConfigModel>().Resource.Uri;

// then we could create named http client with above uri
// ......
}}

Testing

Suppose we got below azure function with type of timer trigger:

[FunctionName("SaveXXXXXXDataToBlobJob")]
public void SaveXXXXXXDataToBlobJob([TimerTrigger("0 3 21 * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"Timer trigger function executed at: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
// your business logic
// ......
}

How to testing our azure function under local environment? You might not expect to wait for the timer fired or modify your schedule (CRON) expression to fire function in instance time (maybe less than 5 seconds).

The best approach would be using azure core tools’ admin mode. Then you could request a http post looks like-> http://localhost:7071/admin/functions/{your_function_name}.

As above postman show that with JSON body : {“input”: “”} even the trigger function with type of timer that we could easily fire under developer stage:)

The alternative way would be:

[FunctionName("SaveXXXXXXDataToBlobJob")]
public void SaveXXXXXXDataToBlobJob(
[TimerTrigger("0 3 21 * * *")]TimerInfo myTimer
#if DEBUG
, RunOnStartup = true
#endif

, ILogger log)
{
log.LogInformation($"Timer trigger function executed at: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
// your business logic ......
}

The key point here we used directives to defined if we are under DEBUG flag existed then RunOnStartup should effect. Ugly but works!

Please make sure to install nuget package: Microsoft.NET.Sdk.Functions so that if we could hook Azure Functions Core Tools with your application under Visual Studio.

Reference

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store