Getting Started
Benzene's promise is write your message handler once, host it anywhere. Your logic lives in a handler that knows nothing about HTTP, Lambda, or queues; a thin bit of host wiring connects it to whatever platform you deploy on. So the fastest way to get started is to start on the platform you're actually deploying to — pick it below.
Just want to see the shape first? Every guide builds the same tiny thing and differs only in the host wiring. If you have no platform in mind yet, the AWS Lambda guide is the best tour of what makes Benzene worth it — one function, many event sources.
Pick your platform
| You're deploying to… | Guide | Runnable example |
|---|---|---|
| AWS Lambda — API Gateway, SQS, SNS, EventBridge (the flagship: one function, every event source) | Getting Started: AWS Lambda | examples/Aws/Benzene.Examples.Aws.Minimal |
| Azure Functions — HTTP + Service Bus, Event Hubs, Event Grid, Cosmos DB, Timer | Getting Started: Azure Functions | examples/Azure |
| Google Cloud Functions — HTTP + Pub/Sub | Getting Started: Google Cloud Functions | examples/Google |
| Kubernetes — HTTP, SQS, Kafka, one handler in a single container/Deployment | Getting Started: Kubernetes | examples/K8sTransports |
| ASP.NET Core — a plain web app or API | Getting Started: ASP.NET Core | examples/Asp/Benzene.Example.Asp.Minimal |
Other hosts have their own guides too: Worker Services (Kafka, HTTP,
Service Bus, Event Hubs, Cosmos DB Change Feed in a long-running process), gRPC,
Kafka, RabbitMQ, and
Cloudflare Containers. Prefer scaffolding? The
project templates give you dotnet new starters for every host.
The one idea they all share
Whichever guide you pick, you write the same three things — and only the third changes between platforms:
A message handler — your logic. It receives a typed request and returns a typed response wrapped in a result. It knows nothing about the transport.
[Message("order:placed")] public class PlaceOrderMessageHandler : IMessageHandler<OrderPlaced, OrderAccepted> { public Task<IBenzeneResult<OrderAccepted>> HandleAsync(OrderPlaced message) { /* ... */ } }A topic — the stable string (
order:placed) every transport routes by. Handlers are discovered by reflection, so there's no routing table to maintain.The host wiring — the only platform-specific part. On AWS it's
app.UseAwsLambda(aws => aws.UseApiGateway(...).UseSqs(...)); on ASP.NET it'sapp.UseBenzene(b => b.UseHttp(...)); on Google Cloud it'sGoogleCloudFunctionHost<Startup>. The handler above is byte-for-byte identical in every one.
That's the portability Benzene's hexagonal design buys you: the handler is the asset; the host is a detail. See Message Handlers and Middleware for the full model, and Hosting for how each platform is wired.
Prerequisites (all platforms)
- .NET 10 SDK and any editor (Visual Studio, Rider, or VS Code).
- Benzene's packages are prerelease (
-alpha) until 1.0, sodotnet add package … --prereleaseis required. Each guide lists the specific packages for its host.
Ready? Pick your platform and go.