✅ Style: No central orchestrator → services talk via events
✅ Flow: Each service emits an event → others react & continue
✅ Rollback: Compensating events
📦 Example – Order Workflow (Event-driven)
Scenario:
Order Service → creates order → publishes OrderCreated
Payment Service → listens to OrderCreated
, reserves money → publishes PaymentCompleted
(or PaymentFailed
)
Inventory Service → listens to PaymentCompleted
, updates stock → publishes InventoryUpdated
If any failure → publish compensation events (OrderCancelled
, PaymentRefunded
)
🖥️ C# Example
// Event definitions
public record OrderCreated(Guid OrderId);
public record PaymentCompleted(Guid OrderId);
public record PaymentFailed(Guid OrderId);
public record InventoryUpdated(Guid OrderId);
// Simple Event Bus (Pub/Sub)
public class EventBus
{
private readonly Dictionary<Type, List<Func<object, Task>>> _handlers = new();
public void Subscribe<T>(Func<T, Task> handler)
{
if (!_handlers.ContainsKey(typeof(T)))
_handlers[typeof(T)] = new List<Func<object, Task>>();
_handlers[typeof(T)].Add(async e => await handler((T)e));
}
public async Task Publish<T>(T @event)
{
if (_handlers.ContainsKey(typeof(T)))
foreach (var handler in _handlers[typeof(T)])
await handler(@event);
}
}
Services
public class OrderService
{
private readonly EventBus _bus;
public OrderService(EventBus bus) => _bus = bus;
public async Task CreateOrder(Guid orderId)
{
Console.WriteLine("✅ Order Created");
await _bus.Publish(new OrderCreated(orderId));
}
}
public class PaymentService
{
private readonly EventBus _bus;
public PaymentService(EventBus bus)
{
_bus = bus;
_bus.Subscribe<OrderCreated>(HandleOrderCreated);
}
private async Task HandleOrderCreated(OrderCreated e)
{
Console.WriteLine("💳 Payment Reserved");
await _bus.Publish(new PaymentCompleted(e.OrderId));
}
}
public class InventoryService
{
public InventoryService(EventBus bus)
{
bus.Subscribe<PaymentCompleted>(HandlePaymentCompleted);
}
private async Task HandlePaymentCompleted(PaymentCompleted e)
{
Console.WriteLine("📦 Inventory Updated for Order " + e.OrderId);
}
}
Usage
var bus = new EventBus();
var orderService = new OrderService(bus);
var paymentService = new PaymentService(bus);
var inventoryService = new InventoryService(bus);
await orderService.CreateOrder(Guid.NewGuid());
🌍 Real-World Example
📌 Interview Quick Notes
Orchestration = Central coordinator.
Choreography = Event-driven, decentralized.
Use when services should be loosely coupled.
Harder to track/monitor (no central brain).