Provides the two-phase event publishing pipeline: an in-process queue (
IEventQueue) drained by a singlePublishAsync()call, with destination resolution and CloudEvents formatting wired in.
The publishing namespace defines the end-to-end flow for dispatching EventData to an underlying messaging transport. Application and infrastructure code interacts solely with the IEventQueue / IEventPublisher abstractions, keeping business logic decoupled from any specific message broker.
Events are first added to an in-process LinkedList-backed queue via the Add(...) overloads. When the unit of work commits, PublishAsync() drains the entire queue in one call to the transport-specific OnPublishAsync implementation. Before dispatch each EventData is formatted via IEventFormatter (which populates CloudEvents attributes and tracing headers) and paired with a resolved destination name via IDestinationProvider, producing a DestinationEvent record. Rollback(count) and Reset() allow the outbox relay or retry logic to undo or restart queued events without data loss.
Transport-specific publisher implementations (e.g. Azure Service Bus, RabbitMQ) inherit from EventPublisherBase and only need to implement OnPublishAsync(DestinationEvent[], CancellationToken).
- 📤 In-process queue: Thread-safe
Add(...)overloads acceptEventData,CloudEvent, named-destination variants, andDestinationEventdirectly;IsEmpty,Count, andGetEvents()allow the host to inspect state before flushing. - 🔒 Single-publish guard:
HasBeenPublishedprevents accidental double-dispatch;Reset()clears the guard and queue for replay or retry scenarios. - ↩️ Rollback support:
Rollback(count)removes the last n Add operations from the queue without clearing earlier entries — useful for partial-failure recovery in outbox relays. - 📍 Destination resolution:
IDestinationProvidermaps each event to a topic/queue name viaCreateFrom(EventData),CreateFrom(string), orCreateNew(MessageType, domainName);FixedDestinationProviderroutes all events to a single configurable destination, reading a default from configuration. - 📊 OpenTelemetry instrumentation:
EventPublisherInvokerwrapsOnPublishAsyncin a diagnostic activity span. - 🔇 No-op publisher:
NoOpEventPublishersilently discards all events — suitable for testing and stub environments.
| Type | Description |
|---|---|
IEventQueue |
Core queuing contract: Add(EventData), Add(destination, EventData), Add(destination, CloudEvent), Add(DestinationEvent), Clear(), IsEmpty, Count. |
IEventPublisher |
Extends IEventQueue with PublishAsync(), HasBeenPublished, Reset(), Rollback(count), and GetEvents(). |
EventPublisherBase |
Thread-safe abstract base; wires formatting, destination resolution, single-publish guard, and OpenTelemetry; implementors override OnPublishAsync. |
IDestinationProvider |
Resolves destination (topic/queue) names from EventData, a string, or MessageType + domain name. |
FixedDestinationProvider |
IDestinationProvider that routes all events to a single destination; defaults to the CoreEx.Events:Destination configuration key or "default". |
DestinationEvent |
Immutable record pairing a resolved destination name with a formatted CloudEvent; passed to OnPublishAsync. |
EventPublisherInvoker |
InvokerBase subclass that wraps publish operations with OpenTelemetry activity spans. |
NoOpEventPublisher |
Silent IEventPublisher implementation that discards all events without error. |
CoreEx.Events- Parent package; definesEventData,IEventFormatter, andMessageTypeconsumed by this pipeline.CoreEx.Events.Subscribing- Complementary subscribing pipeline that receives and dispatches incoming events.CoreEx.Database.Outbox- Outbox publisher wrapsIEventPublisher; events are persisted transactionally then flushed to the transport by a relay host.