Event-Driven Workflows
The Extensions.Events package enables workflows that publish and wait for events, supporting choreography-based coordination.
Installation
dotnet add package WorkflowFramework.Extensions.Events
IEventBus
using WorkflowFramework.Extensions.Events;
public interface IEventBus
{
Task PublishAsync(WorkflowEvent evt, CancellationToken ct = default);
IDisposable Subscribe(string eventType, Func<WorkflowEvent, Task> handler);
Task<WorkflowEvent?> WaitForEventAsync(string eventType, string correlationId, TimeSpan timeout, CancellationToken ct = default);
}
InMemoryEventBus
A built-in in-memory implementation with dead letter support:
var eventBus = new InMemoryEventBus();
// Subscribe
using var sub = eventBus.Subscribe("OrderCompleted", async evt =>
{
Console.WriteLine($"Order {evt.CorrelationId} completed!");
});
// Publish
await eventBus.PublishAsync(new WorkflowEvent
{
EventType = "OrderCompleted",
CorrelationId = "order-123",
Payload = { ["Total"] = 99.95 }
});
// Undelivered events go to dead letters
var deadLetters = eventBus.DeadLetters;
PublishEventStep
Publishes an event from within a workflow:
var workflow = new WorkflowBuilder()
.PublishEvent(eventBus, "OrderCreated")
.Build();
await workflow.RunAsync(context);
var eventId = context.Properties["PublishEvent.EventId"];
WaitForEventStep
Pauses the workflow until a matching event arrives (or timeout):
var workflow = new WorkflowBuilder()
.PublishEvent(eventBus, "PaymentRequested")
.WaitForEvent(eventBus, "PaymentCompleted", timeout: TimeSpan.FromMinutes(30))
.Build();
After the event is received, its payload properties are merged into the context as WaitFor(PaymentCompleted).{key}.
Builder Extensions
using WorkflowFramework.Extensions.Events;
// Shorthand via fluent builder
builder
.PublishEvent(eventBus, "StepCompleted", name: "NotifyDone")
.WaitForEvent(eventBus, "Approval", TimeSpan.FromHours(1), name: "WaitApproval");
Note
The InMemoryEventBus is suitable for single-process scenarios. For distributed systems, implement IEventBus over a message broker like RabbitMQ or Azure Service Bus.