Skip to content

Samples

Every messaging pattern in the Learn section has a matching runnable example in the examples/ folder of the repository. They are full console apps: no stubs, no mocks, real RabbitMQ (and MongoDB where persistence is needed) running in Docker.

Every sample expects a RabbitMQ broker and — for the persistence-backed ones — a MongoDB instance. One docker-compose file starts them both:

Terminal window
docker compose -f examples/docker-compose.yml up -d

Each sample’s run.sh (or run.ps1 on Windows) launches the sender and consumer(s) in the right order with sensible pauses between them. If you want to see the individual invocations, the sample’s README lists the raw dotnet run commands.

Each row below has a brief description, the pattern it illustrates, and a link to the source.

Send one command from one sender to one consumer queue — the simplest shape.

Publish one event; several independent subscribers each get their own copy.

Send a request, wait for a reply — async under the hood, blocking at the call site.

Two workers share a queue; each message goes to one of them — horizontal throughput.

Publish split-by-type events; different consumers bind to the types they care about.

Publish derived events; a base-type handler catches the whole category while specific handlers catch one type.

Ordered multi-stage pipeline: inventory → billing → shipping. Stages don’t know each other.

Send the same request to several responders in parallel; collect replies into one list.

Buffer telemetry slices and flush by size or by time — batching as the unit of work.

A saga coordinating order submission, inventory reservation, and payment across three services — state persisted in MongoDB.

Stamp an X-Trace-Id header on every outgoing message — filters as the cross-cutting hook.

Runnable end-to-end demo of how to build your own filter and middleware against the public extension points. The worked scenario is broker-redelivery deduplication using the OnConsumedSuccessfully pipeline stage.

IFilter · IMessageProcessingMiddleware · examples/CustomFilterAndMiddleware

Chunk a payload too large for one message, reassembled on the receiver, one handler invocation at the end.

End-to-end OpenTelemetry tracing across publish → consume, demonstrating W3C trace-context propagation through the broker. Three processes share one TraceId; each subscriber’s span is a direct child of the publisher’s.

Concurrency / soak / throughput harness over every pattern. Surfaces cross-tenant routing leaks, deadlocks, memory growth, and lifecycle races against two Bus instances.

Each sample’s processes print status lines in a uniform shape:

  • READY:<name> — the consumer is listening.
  • SUCCESS:<name>:<what happened> — a message was handled.

So a Point-to-Point run produces:

READY:point-to-point-consumer
SUCCESS:point-to-point-sender:sent work-001
SUCCESS:point-to-point-consumer:processed work-001

That shape is deliberately minimal — enough to follow the sequence across terminals, not so much that it obscures the messaging itself. If you want more, each sample is just a few hundred lines of C#; read the source.

  • Docker services not up: docker compose -f examples/docker-compose.yml ps should show RabbitMQ (and MongoDB for the persistence-backed samples) in a healthy state.
  • Handlers don’t fire: check the RabbitMQ management UI at http://localhost:15672 (guest/guest). Each example’s README lists the queue names it declares.
  • MongoDB-backed samples fail to start: the Mongo container takes a few seconds longer than RabbitMQ. The samples’ DependencyWaiter handles this; if you’re running dotnet run manually, start the consumer and wait a moment before the sender.