This project is an event-driven ASP.NET Core system built around RabbitMQ. When creating this project, i focused on reliable messaging, clear service boundaries, and correct handling of distributed workflows
Rather than trying to create a full production platform the scope is severely reduced, only focusing on asynchronous communication and eventual consistency using the outbox pattern
The system is composed of multiple services that communicate through RabbitMQ:
- Creates orders
- Stores OrderCreatedEvent in the outbox
- Publishes events via background worker
- Creates pending payments from order events
- Completes payments via API
- Publishes PaymentCompletedEvent
- Consumes payment events
- Updates product stock
- Prevents duplicate processing Each service owns its own data and communicates using events
- Event-driven communication using RabbitMQ
- Outbox pattern for reliable message publishing
- Inventory updates driven by payment events
- Clear separation between controller, service, and messaging layers
- Manual message acknowledgements for safe processing
- Idempotent consumers using MessageId tracking
- Order creation with generated PaymentId
- Payment lifecycle with pending and completed states
- DTO-based request/response models
The system is designed around at-least-once delivery and eventual consistency.
- Each message includes a MessageId
- Consumers track processed messages
- Duplicate messages are safely ignored
- Messages are acknowledged only after successful processing
- Failed messages are requeued automatically
- C#
- ASP.NET Core
- Entity Framework Core
- SQLite
- RabbitMQ
- BackgroundService
docker run -d --name rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
rabbitmq:3-managementManagement UI:
http://localhost:15672
guest / guest
Start each service individually:
dotnet run- POST
/orders→ creates order and returns PaymentId - POST
/payments→ completes payment Inventory updates automatically via events