Philiprehberger.Outbox
0.2.1
dotnet add package Philiprehberger.Outbox --version 0.2.1
NuGet\Install-Package Philiprehberger.Outbox -Version 0.2.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Philiprehberger.Outbox" Version="0.2.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Philiprehberger.Outbox" Version="0.2.1" />
<PackageReference Include="Philiprehberger.Outbox" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Philiprehberger.Outbox --version 0.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Philiprehberger.Outbox, 0.2.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Philiprehberger.Outbox@0.2.1
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Philiprehberger.Outbox&version=0.2.1
#tool nuget:?package=Philiprehberger.Outbox&version=0.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Philiprehberger.Outbox
Transactional outbox pattern implementation for reliable event/message publishing.
Installation
dotnet add package Philiprehberger.Outbox
Usage
using Philiprehberger.Outbox;
builder.Services.AddOutbox(options =>
{
options = options with
{
PollingInterval = TimeSpan.FromSeconds(10),
BatchSize = 50,
MaxRetries = 5
};
});
builder.Services.AddSingleton<IOutboxStore, MyEfCoreOutboxStore>();
builder.Services.AddSingleton<IOutboxDispatcher, MyRabbitMqDispatcher>();
Saving Messages
using Philiprehberger.Outbox;
var message = new OutboxMessage(
Id: Guid.NewGuid(),
Type: "OrderPlaced",
Payload: JsonSerializer.Serialize(order),
CreatedAt: DateTimeOffset.UtcNow);
await outboxStore.SaveAsync(message);
Message Priority
using Philiprehberger.Outbox;
var urgent = new OutboxMessage(
Id: Guid.NewGuid(),
Type: "PaymentFailed",
Payload: JsonSerializer.Serialize(payment),
CreatedAt: DateTimeOffset.UtcNow,
Priority: MessagePriority.Critical);
await outboxStore.SaveAsync(urgent);
Deduplication with Idempotency Keys
using Philiprehberger.Outbox;
var message = new OutboxMessage(
Id: Guid.NewGuid(),
Type: "OrderPlaced",
Payload: JsonSerializer.Serialize(order),
CreatedAt: DateTimeOffset.UtcNow,
IdempotencyKey: $"order-placed-{order.Id}");
await outboxStore.SaveAsync(message);
Dead Letter Queue
using Philiprehberger.Outbox;
// Default in-memory DLQ is registered automatically.
// Replace with your own implementation for production:
builder.Services.AddSingleton<IDeadLetterStore, MyDatabaseDeadLetterStore>();
// Inspect dead-lettered messages:
var dlq = serviceProvider.GetRequiredService<IDeadLetterStore>();
var failed = await dlq.GetAllAsync();
Diagnostic Events
using Philiprehberger.Outbox;
OutboxDiagnostics.MessageDispatched += msg =>
Console.WriteLine($"Dispatched: {msg.Id} ({msg.Type})");
OutboxDiagnostics.MessageDeadLettered += msg =>
Console.WriteLine($"Dead-lettered: {msg.Id} after {msg.RetryCount} retries");
API
OutboxMessage
| Property | Type | Default | Description |
|---|---|---|---|
Id |
Guid |
Unique message identifier | |
Type |
string |
Message type discriminator | |
Payload |
string |
Serialized message payload (JSON) | |
CreatedAt |
DateTimeOffset |
When the message was created | |
ProcessedAt |
DateTimeOffset? |
null |
When the message was dispatched |
Error |
string? |
null |
Last failure error message |
RetryCount |
int |
0 |
Number of dispatch attempts |
IdempotencyKey |
string? |
null |
Deduplication key (duplicates are skipped) |
Priority |
MessagePriority |
Normal |
Dispatch priority level |
MessagePriority
| Value | Description |
|---|---|
Low |
Dispatched after all higher-priority messages |
Normal |
Default priority |
High |
Dispatched before Normal and Low |
Critical |
Dispatched before all other messages |
IOutboxStore
| Method | Description |
|---|---|
SaveAsync(message, ct) |
Persist a new outbox message |
GetPendingAsync(batchSize, ct) |
Retrieve unprocessed messages |
MarkProcessedAsync(id, ct) |
Mark a message as dispatched |
MarkFailedAsync(id, error, ct) |
Mark a message as failed |
IOutboxDispatcher
| Method | Description |
|---|---|
DispatchAsync(message, ct) |
Dispatch a message to its destination |
IDeadLetterStore
| Method | Description |
|---|---|
AddAsync(message, ct) |
Add a failed message to the dead letter queue |
GetAllAsync(ct) |
Retrieve all dead-lettered messages |
OutboxOptions
| Property | Type | Default | Description |
|---|---|---|---|
PollingInterval |
TimeSpan? |
5 seconds | How often the relay polls for pending messages |
BatchSize |
int |
100 |
Max messages per polling cycle |
MaxRetries |
int |
3 |
Max dispatch attempts before dead-lettering |
OutboxDiagnostics
| Event | Description |
|---|---|
MessageEnqueued |
Raised when a message is saved to the outbox |
MessageDispatched |
Raised when a message is successfully dispatched |
MessageFailed |
Raised when a dispatch attempt fails |
MessageDeadLettered |
Raised when a message is moved to the dead letter queue |
OutboxServiceCollectionExtensions
| Method | Description |
|---|---|
AddOutbox(configure?) |
Register the outbox relay service, options, and default DLQ |
Development
dotnet build src/Philiprehberger.Outbox.csproj --configuration Release
Support
If you find this project useful:
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.