Event Types
Domain Events
Domain events are internal to the bounded context and published viaICommandQueryBus using MediatR.
DomainEvent Base Class
Core.Application.ComandQueryBus/Notifications/DomainEvent.cs:3
Properties:
EventDateUtc- Timestamp when the event occurred (UTC)
IRequestNotification
Marker interface for domain events (extends MediatR’sINotification).
Core.Application.ComandQueryBus/Notifications/IRequestNotification.cs:5
Integration Events
Integration events are used for communication between bounded contexts or microservices, typically via message brokers.IntegrationEvent Base Class
Core.Application.EventBus/Events/IntegrationEvent.cs:5
Properties:
Id- Unique identifier for the eventCreateDateUtc- When the event was createdEventType- Type/category of the eventSubject- Subject or topic of the eventData- Event payload (any serializable object)
Domain Event Example
DummyEntityCreated
Domain event published when a new entity is created.Application/DomainEvents/DummyEntityCreated.cs:10
Publishing Domain Events
Domain events are published viaICommandQueryBus in command handlers:
Application/UseCases/DummyEntity/Commands/CreateDummyEntity/CreateDummyEntityHandler.cs:34
Integration Event Example
DummyEntityCreatedIntegrationEvent
Integration event for cross-service communication.Application/Integrations/Events/DummyEntityCreatedIntegrationEvent.cs:5
Event Handlers
Integration Event Handler Interface
Core.Application.EventBus/Handlers/IIntegrationEventHandler.cs:3
Type Parameters:
TEvent- The integration event type to handle
Task Handle(TEvent @event)- Processes the integration event
Publisher Handler Example
Handler that publishes integration events to external systems.Application/Integrations/Handlers/Publishers/DummyEntityCreatedIntegrationEventHandlerPub.cs:5
Event Bus Interface
Core.Application.EventBus/Buses/IEventBus.cs:3
Methods:
Publish()- Publishes an integration event to subscribersSubscribe<TEvent, THandler>()- Registers a handler for an event typeUnsubscribe<TEvent, THandler>()- Removes a handler registrationSubscribeDynamic()- Registers a dynamic handler by event nameUnsubscribeDynamic()- Removes a dynamic handler
Event Handling Lifecycle
Domain Event Flow
- Command Execution - Handler processes command and persists entity
- Event Creation - Map entity to domain event using
entity.To<TEvent>() - Domain Event Publishing - Publish via
ICommandQueryBus.Publish() - Event Handler Execution - MediatR routes to registered handlers
- Integration Event Publishing - Handlers optionally publish to
IEventBus - External Distribution - Event bus sends to message broker
Integration Event Flow
Command Query Bus
ICommandQueryBus Interface
Used for publishing domain events within the bounded context.Core.Application.ComandQueryBus/Buses/ICommandQueryBus.cs:5
Methods:
Publish<TNotification>()- Publishes domain events (notifications)Send()- Sends commands/queries without return valueSend<TResponse>()- Sends commands/queries with return value
Best Practices
Event Naming
Event Naming
- Use past tense:
EntityCreated,OrderShipped,PaymentProcessed - Be specific and descriptive
- Domain events:
[Entity][Action](e.g.,DummyEntityCreated) - Integration events: Append
IntegrationEventsuffix
Domain vs Integration Events
Domain vs Integration Events
Use Domain Events when:
- Communication within same bounded context
- Triggering immediate side effects (e.g., sending email)
- Updating read models or projections
- Business logic coordination
- Communication between bounded contexts
- Cross-service messaging
- Event sourcing
- Asynchronous processing
Event Data
Event Data
- Include all data needed by subscribers
- Avoid including sensitive information
- Keep events immutable (private setters)
- Version events for backward compatibility
- Domain events: Include entity state
- Integration events: Use
Dataproperty for payload
Publishing Events
Publishing Events
- Publish domain events AFTER persistence succeeds
- Use transactions to ensure consistency
- Pass
cancellationTokenfor cancellation support - Handle publishing failures gracefully
- Consider idempotency for integration events
Event Handlers
Event Handlers
- Keep handlers focused and simple
- Handlers should be idempotent
- Use separate handlers for different concerns
- Don’t throw exceptions for non-critical failures
- Log handler execution for debugging
Event Types Comparison
| Aspect | Domain Event | Integration Event |
|---|---|---|
| Scope | Bounded context | Cross-service |
| Transport | MediatR (in-process) | Message broker |
| Base Class | DomainEvent | IntegrationEvent |
| Interface | IRequestNotification | IntegrationEvent |
| Publisher | ICommandQueryBus | IEventBus |
| Serialization | Not serialized | JSON serialized |
| Timing | Synchronous | Asynchronous |
| Use Case | Internal coordination | External integration |