Portal Community

Settings Pattern

Every executor has a settings class that extends BaseNodeExecutorSettings. The base class provides typed reader helpers (ReadConfigByKey, ReadConfigByKeyBool, etc.) backed by the ConfigDataPropertyBag.

// MyNodeSettings.cs
public class MyNodeSettings : BaseNodeExecutorSettings
{
    // Reads string field from config JSON key "recipientEmail"
    public string RecipientEmail => ReadConfigByKey("recipientEmail", string.Empty)!;

    // Reads boolean field
    public bool SendCopyToSender => ReadConfigByKeyBool("sendCopyToSender", false);

    // Reads integer field
    public int? MaxRetries => ReadConfigByKey_Int("maxRetries");

    // Reads an enum field
    public EmailPriority Priority => ReadConfigByEnum("priority", EmailPriority.Normal);

    // Reads a credential ID (integer reference to a stored credential)
    public int CredentialId => int.Parse(ReadConfigByKey("credentialId", "0")!);

    // Validation — return an error message string, or null if valid
    public override string? Validate()
    {
        if (string.IsNullOrWhiteSpace(RecipientEmail))
            return "RecipientEmail is required.";
        return null;
    }
}

Wiring the Settings Class

Override CreateExecutorSettings() in the Config partial class to tell the base which settings type to instantiate:

// MyNodeExecutor.Config.cs
public partial class MyNodeExecutor
{
    // Typed accessor for convenience in ExecuteInternalAsync
    private MyNodeSettings? mySettings => settings as MyNodeSettings;

    // Tells BaseNodeExecutor to use your settings class
    public override BaseNodeExecutorSettings CreateExecutorSettings()
        => new MyNodeSettings();
}

Using Settings in ExecuteInternalAsync

protected override async Task<NodeExecutionResult> ExecuteInternalAsync(
    NodeExecutionContext ctx,
    CancellationToken ct)
{
    // settings is already populated by the time this is called
    var s = mySettings!;

    var recipient = s.RecipientEmail;       // "alice@example.com"
    var maxRetries = s.MaxRetries ?? 3;     // 3 (default if not set)

    // For credentials: resolve via ICredentialResolver (never read raw secret from config)
    var password = await _credentialResolver.GetPasswordAsync(s.CredentialId, ct);

    // ... use recipient, password, etc. ...
}

Available Reader Methods on BaseNodeExecutorSettings

MethodReturn TypeUsage
ReadConfigByKey(key)string?String fields, defaults to empty string
ReadConfigByKey(key, default)string?String with explicit default
ReadConfigByKeyBool(key)boolBoolean, defaults to false
ReadConfigByKeyBool(key, default)boolBoolean with explicit default
ReadConfigByKey_Int(key)int?Nullable integer
ReadConfigByEnum<T>(key, default)TEnum value with fallback
ReadConfigNodeByKey(key)JsonNode?Nested JSON object/array
ReadConfigDictionaryByKey(key)Dictionary<string,object>Nested object as dictionary
Configuration Keys Are Case-Sensitive The key string you pass to ReadConfigByKey("myField") must exactly match the field key in the Atlas Form definition. A mismatch returns the default value silently. Validate your Atlas Form field keys against your settings class before deploying.
Credentials Must Use ICredentialResolver Never read raw passwords, API keys, or tokens from the configuration JSON. The Atlas Form stores a credential ID (integer), and your executor calls ICredentialResolver.GetPasswordAsync(credentialId) to retrieve the actual secret from the secure credential store at runtime.