Tips and Tricks #183: Implement Domain Events for Loose Coupling

Use domain events to decouple components and enable reactive architectures.

Code Snippet

// Domain Event
public record OrderPlacedEvent(
    string OrderId,
    string UserId,
    decimal TotalAmount,
    DateTime PlacedAt
);

// Event Publisher
public interface IEventPublisher
{
    Task PublishAsync(T @event) where T : class;
}

// In Order aggregate
public class Order
{
    private readonly List _events = new();
    
    public void Place()
    {
        Status = OrderStatus.Placed;
        _events.Add(new OrderPlacedEvent(Id, UserId, Total, DateTime.UtcNow));
    }
    
    public IReadOnlyList GetEvents() => _events;
}

// Event Handler (separate bounded context)
public class InventoryEventHandler
{
    public async Task Handle(OrderPlacedEvent e)
    {
        await _inventory.ReserveItemsAsync(e.OrderId);
    }
}

Why This Helps

  • Decouples bounded contexts
  • Enables eventual consistency patterns
  • Supports audit trails and event sourcing

How to Test

  • Verify events are raised correctly
  • Test handlers in isolation

When to Use

Microservices, complex domains, when actions trigger side effects in other modules.

Performance/Security Notes

Consider idempotency for event handlers. Use outbox pattern for reliable publishing.

References


Try this tip in your next project and share your results in the comments!


Discover more from Code, Cloud & Context

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.