Configuration is the process of specifying settings and parameters that control the behavior of an application. The sections below show how to access Configuration settings and to monitor for changes in the configuration at runtime. The SDK constructs the configuration using several sources, as described in the Configuration Sources section.
Configuration setting values are accessed using a singleton and are accessed hierarchically by separating the levels of the hierarchy with colons.
Examples:
All examples use the following configuration:
AEA.json:
{
"App" : {
"SomeSetting": true,
"Fruit": [ "Apple", "Banana", "Pear" ],
"FruitObjects": [ {"Name": "Apple"}, {"Name": "Banana"}, {"Name": "Pear"}]
}
}using static Agora.SDK;
...
Console.Writeline(Config["App:SomeSetting"]);from agoraiot import config
...
print( config["App:SomeSetting"] )using static Agora.SDK;
using Microsoft.Extensions.Configuration;
...
var fruits = Config.GetSection("App:Fruit").Get<List<string>>();
foreach(var fruit in fruits)
Console.WriteLine(fruit);from agoraiot import config
fruits = config["App:Fruit"]
for fruit in fruits:
print( fruit )Output:
Apple
Banana
Pear[!IMPORTANT] For .NET, one typically deploys containers using single, trimmed executables. Configration binding and autopopulation of object elements can fail at run-time due required code for the functionality is trimmed, making the deployed application run differently than during development. To fix this issue, Microsoft introduced > a project setting that affects .NET 8 to enable auto-generation of binding code.
To enable this feature, add
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>to<PropertyGroup>in the csproj files using configuration / objecting binding.
using static Agora.SDK;
using Microsoft.Extensions.Configuration;
class Fruit { public string Name { get; set; } }
List<Fruit> fruits = Config.GetSection("App:FruitObjects").Get<List<Fruit>>();
foreach(var fruit in fruits)
Console.WriteLine(fruit.Name);
// example using binding
List<Fruit> fruits = [];
Config.GetSection("App:FruitObjects").Bind(fruits);from agoraiot import config
class Fruit:
def __init__(self, name):
self.name = name
fruits = config["App:FruitObjects"]
for fruitdata in fruits
fruit = Fruit(fruitdata["Name"])
# to deserialize directly you will need to create custom json encoders/decodersThe configuration is built from a set of sources that starts with Defaults and ends with Overrides as shown in Configuration Overview.
To set defaults or overrides use the Defaults or Overrides dictionaries.
using static Agora.SDK;
...
Config.Defaults["App:SettingName"] = "Default value if none provided";
Config.Overrides["App:OtherSettingName"] = "Overrides all other sources";
Config.Build();
from agoraiot import config
...
config.defaults["App:SettingName"] = "Default value if none provided";
config.overrides["App:OtherSettingName"] = "Overrides all other sources";
config.build()The alternate configuration and any Key-Per-File settings allow application settings to be modified while the application is running. An application should monitor the Configuration (as a whole) or an individual settings has changed if a run-time change is allowed.
Config.Changed += ConfigChanged;
...
private void ConfigChanged(object? sender, EventArgs e)
{
"Configuration Changed".LogInfo();
}def config_change_handler():
logger.info("Configuration Changed")
config.observe_config( config_change_handler )var mySetting = Agora.ObservableSetting.Get("AEA2:LogLevel");
mySetting.PropertyChange += SettingChange;
...
private void SettingChange( object? sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
if (sender is Agora.ObservableSetting o)
$"Setting Changed to `{o.Value}'".LogInfo();
}def setting_changed(val):
logger.info(f"Setting Changed to {val}")
config.observe("AEA2:LogLevel", setting_changed )using Microsoft.Extensions.Configuration;
var json = Config.SerializeToJson();
if ( json != null )
json.ToJsonString(new JsonSerializerOptions() { WriteIndented = true }).LogInfo();from agoraiot import config, logger
import json
logger.info( json.dumps(config, indent=4) )