Architecture

Benzene separates what your service does from how it's invoked. A handler holds your logic; a transport turns a native request into a message and routes it through a shared middleware pipeline. Ports and adapters, applied plainly, is where everything else on this page comes from.

Ports and adapters

The design principles are explicit and the core concepts are small.

Handlers are the core

A message handler is IMessageHandler<TRequest, TResponse>: ordinary C# that takes a typed request and returns a typed result. It has no idea what transport carried it.

Transports are adapters

HTTP, SQS, SNS, Kafka, EventBridge, Event Hub, Service Bus, gRPC. Each is an adapter that maps a native event onto a message and back, so adding a vendor means writing an adapter, never touching the core.

One pipeline through all of them

Every adapter runs the same composable middleware pipeline, so cross-cutting behavior is written once and applies everywhere, rather than being re-implemented per event source.

One model, many transports, at once

The point isn't swapping clouds. It's that the same handler is reachable over many transports at once, on the cloud you already run.

Mix transports in one service

Expose a handler over HTTP for callers and over a queue for async work in the same host, with one line of wiring each. On serverless that normally means separate, trigger-locked functions.

Host it unchanged

The same BenzeneStartUp runs on AWS Lambda, Azure Functions, a self-hosted worker, or ASP.NET Core: one application definition, several ways to start it.

Reach the native context when you must

Abstractions don't trap you. IBenzeneInvocation and typed features are the escape hatch to the underlying platform object when a handler genuinely needs it.

Introspectable by design

A Benzene service describes itself, its topics, payloads, and contracts, from the same code that handles messages. There's no hand-maintained diagram to drift out of date.

OpenAPI + AsyncAPI from your code

Spec generation derives OpenAPI (HTTP) and AsyncAPI (events) documents from the handler registry, with example payloads and validation rules included.

Browse it in the Spec UI

A self-contained Spec UI renders that contract: topics, payload tables, validation chips, transport chips. Open the live demo →

A map across services

Aggregate every service's contract and health into a searchable service map with contract-drift detection and cross-service topology. Open the live demo → (the mesh tooling is shipped and evolving.)

Composable, swappable, standards-friendly

The seams are deliberate, so Benzene slots into your stack rather than dictating it.

Your DI, your serializers

Microsoft DI by default, with an Autofac option; System.Text.Json by default, with Newtonsoft, XML, Avro, and MessagePack available, chosen per content type and swappable by registration.

Middleware is the extension point

Auth, validation, resilience, logging, idempotency: each is middleware you add, reorder, or replace. Your own concerns plug in the same way.

Interop on open envelopes

A transport-agnostic wire envelope (topic, headers, body) and standards-based specs let Benzene services interoperate across vendors and with non-Benzene consumers.

Read the docs Run it in production →