Configuration Reference
Benzene builds on the standard Microsoft.Extensions.Configuration and
Microsoft.Extensions.DependencyInjection stacks — there's no bespoke configuration system to
learn. This page covers how a service is configured: the start-up lifecycle, where configuration
values come from on each host, and the option classes individual packages expose.
The BenzeneStartUp lifecycle
BenzeneStartUp (in Benzene.Microsoft.Dependencies) is the platform-neutral application
definition. You derive from it once and run the same class on any host — AWS Lambda, Azure
Functions, ASP.NET Core, a self-hosted worker — because it knows nothing about the transport.
public abstract class BenzeneStartUp
{
public virtual IConfiguration GetConfiguration()
=> new ConfigurationBuilder().AddEnvironmentVariables().Build();
public abstract void ConfigureServices(IServiceCollection services, IConfiguration configuration);
public abstract void Configure(IBenzeneApplicationBuilder app, IConfiguration configuration);
}
The three members run in order, once, on start-up (cold start on serverless hosts):
| Member | Runs | Responsibility |
|---|---|---|
GetConfiguration() |
first | Build and return the IConfiguration for the service. Its result is passed into both methods below. Virtual: the default reads environment variables, so override it only when you need a different source. |
ConfigureServices(services, configuration) |
second | Register services and handlers with DI — services.UsingBenzene(x => x.AddMessageHandlers(...)), your repositories, validators, etc. |
Configure(app, configuration) |
third | Build the middleware pipeline — app.UseAwsLambda(...), app.UseHttp(...), and the steps inside them. |
public class StartUp : BenzeneStartUp
{
// GetConfiguration() not overridden: the default reads environment variables —
// what a container, a Lambda, a Function and a Cloud Run revision all inject.
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration) =>
services.UsingBenzene(x => x
.AddMessageHandlers(typeof(MyHandler).Assembly));
public override void Configure(IBenzeneApplicationBuilder app, IConfiguration configuration) =>
app.UseAwsLambda(events => events
.UseApiGateway(http => http.UseMessageHandlers()));
}
Building configuration
GetConfiguration() returns a plain IConfiguration, so any configuration provider works —
environment variables, JSON files, AWS Systems Manager Parameter Store, AWS Secrets Manager,
Azure App Configuration, and so on. An override replaces the default (it does not merge with
it), so include .AddEnvironmentVariables() yourself if you still want them:
public override IConfiguration GetConfiguration() =>
new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("config.json", optional: true)
.AddEnvironmentVariables()
.Build();
Microsoft.Extensions.Configuration and its environment-variables provider are referenced by
Benzene.Microsoft.Dependencies (they back the default), so they're already available; add the
specific provider packages beyond that yourself (.Json, .FileExtensions for SetBasePath,
cloud providers). Read values in ConfigureServices/Configure with configuration["Key"] or
bind sections with configuration.GetSection(...).Get<T>().
Where configuration comes from per host
Each host has a natural configuration source; the BenzeneStartUp above stays the same:
| Host | Typical source |
|---|---|
| AWS Lambda | Environment variables (set in the SAM template, console, or CDK/Terraform), read via .AddEnvironmentVariables(). See AWS Lambda Setup. |
| Azure Functions | local.settings.json locally, Function App application settings when deployed. See Azure Functions Setup. |
| ASP.NET Core | appsettings.json / config.json and environment variables via the standard host builder. See ASP.NET Core. |
Two ways to wire ASP.NET Core
ASP.NET Core supports both the platform-neutral start-up and an inline style:
// A) Platform-neutral BenzeneStartUp — reuse the same class as Lambda/Azure:
builder.UseBenzene<StartUp>(); // runs GetConfiguration + ConfigureServices
var app = builder.Build();
app.UseBenzene(); // runs Configure
// B) Inline — register and configure directly in Program.cs (see Getting Started):
builder.Services.UsingBenzene(x => x.AddMessageHandlers(typeof(MyHandler).Assembly));
var app = builder.Build();
app.UseBenzene(benzene => benzene.UseHttp(http => http.UseMessageHandlers()));
Package configuration option classes
Some packages take a strongly-typed options object rather than raw configuration keys. Populate
these however you like — inline, or bound from IConfiguration.
CorsSettings — Benzene.Http
Passed to UseCors(...).
| Property | Purpose |
|---|---|
AllowedDomains |
Origins allowed to call the API ("*" allows all — avoid in production). |
AllowedHeaders |
Headers echoed in Access-Control-Allow-Headers. |
SqsConsumerConfig — Benzene.Aws.Sqs
Configures the SQS consumer when polling a queue directly (outside a Lambda trigger).
| Property | Default | Purpose |
|---|---|---|
QueueUrl |
— | URL of the queue to consume from. |
MaxNumberOfMessages |
— | Maximum messages fetched per receive call. |
WaitTimeSeconds |
1 |
Long-poll wait time per receive call. |
BenzeneKafkaConfig — Benzene.Kafka.Core
Configures the Kafka consumer/client.
| Property | Default | Purpose |
|---|---|---|
ConsumerConfig |
— | The underlying Confluent ConsumerConfig (brokers, group ID, etc.). |
Topics |
— | Topics to subscribe to. |
ConcurrentRequests |
5 |
Number of records processed concurrently. |
PreserveOrderPerPartition |
true |
Routes same-partition messages to the same dispatcher lane so they're handled in order. |
DrainTimeout |
30s |
How long StopAsync waits for in-flight handlers before abandoning them. |
ConsumeExceptionRetryDelay |
1s |
Backoff between retries after a ConsumeException. |
CatchHandlerExceptions |
true |
Whether an unhandled handler exception is caught and logged (that lane keeps consuming) or left to stop the whole worker. |
CommitOnlyOnSuccess |
false |
Whether an offset is only stored after its handler succeeds (at-least-once, redelivers on failure/crash) instead of being auto-stored as soon as it's consumed. Requires CatchHandlerExceptions = false and PreserveOrderPerPartition = true. |
RaiseOnFailureStatus |
true |
Whether a handler that returns an unsuccessful result without throwing is settled like one that threw — dead-lettered under KafkaDeadLetterOptions, its offset withheld under CommitOnlyOnSuccess, and (under the default auto-store config, where the offset was stored before the handler ran) logged as a warning. |
DrainOnRevoke |
null (→ CommitOnlyOnSuccess) |
Whether a consumer-group rebalance drains in-flight handlers for the revoked partitions and commits their stored offsets before releasing them. |
Retry options — Benzene.Resilience
UseRetry(...) takes its settings as method parameters rather than an options class — see
UseRetry for the full list (numberOfRetries, initialDelay,
backoffFactor, shouldRetry, …).
See also
- Getting Started — configuration in a running service.
- AWS Lambda Setup — Lambda configuration specifics.
- Middleware Reference — the steps you add in
Configure. - Package Reference — which package each option class ships in.