HelloWorld example for sending an object over RabbitMQ via EasyNetQ between two different applications
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To send an object between two different .NET applications with RabbitMQ and EasyNetQ, both applications need to agree on the message contract and connect to the same broker. One app publishes the object, and the other subscribes to that object type and processes incoming messages.
Define a Shared Message Contract
The publisher and consumer should reference the same message type, usually from a small shared class library. That avoids serialization mismatches and keeps routing consistent.
This contract should stay versioned and stable. Once multiple applications depend on it, changing the shape casually can break consumers.
Publisher Application
With current EasyNetQ versions, the bus is typically created from a service collection. The publisher resolves IPubSub and sends the message.
That is enough for a simple publish-subscribe example when RabbitMQ is running locally.
Consumer Application
The receiving application also connects to the same broker and subscribes to the same message type with a stable subscription identifier.
The subscription ID matters because EasyNetQ uses it to manage the queue binding for that subscriber.
Run the Example Across Two Applications
The flow is:
- start RabbitMQ
- run the consumer app
- run the publisher app
- observe the object arriving in the consumer
If the consumer is not running yet, RabbitMQ and EasyNetQ behavior depends on the exchange and queue configuration created by the subscription side. For a first example, start the consumer first so the queue exists and the wiring is easy to reason about.
Keep Serialization and Contracts Simple
For cross-application messaging, simple DTO-style messages work best:
- primitive fields
- timestamps
- identifiers
- small nested objects only when necessary
Avoid sending domain entities with behavior, database connections, or framework-heavy types. A message contract should be portable and serialization-friendly.
Add Basic Operational Safety
Even a Hello World example should point toward production-safe habits:
- use a dedicated shared contract assembly
- keep subscription IDs stable
- log publish and receive failures
- think about versioning before changing message fields
That turns a demo into something you can evolve without rewriting from scratch later.
Common Pitfalls
- Defining the message class differently in the publisher and consumer projects.
- Using different broker connection strings across the two applications.
- Changing the message contract without coordinating both sides.
- Forgetting that the subscription ID influences queue identity and consumer behavior.
- Treating demo code as production-ready without adding error handling and versioning discipline.
Summary
- Share one message contract between the two applications.
- Publish the object through EasyNetQ from the sender application.
- Subscribe to the same message type in the receiver application.
- Use a stable subscription ID and the same RabbitMQ broker configuration on both sides.
- Keep the message DTO simple so cross-application serialization stays reliable.

