EricksonLopez.Outbox.SourceGenerators
1.0.0
See the version list below for details.
Requires NuGet 6.0.0 or higher.
dotnet add package EricksonLopez.Outbox.SourceGenerators --version 1.0.0
NuGet\Install-Package EricksonLopez.Outbox.SourceGenerators -Version 1.0.0
<PackageReference Include="EricksonLopez.Outbox.SourceGenerators" Version="1.0.0" />
<PackageVersion Include="EricksonLopez.Outbox.SourceGenerators" Version="1.0.0" />
<PackageReference Include="EricksonLopez.Outbox.SourceGenerators" />
paket add EricksonLopez.Outbox.SourceGenerators --version 1.0.0
#r "nuget: EricksonLopez.Outbox.SourceGenerators, 1.0.0"
#:package EricksonLopez.Outbox.SourceGenerators@1.0.0
#addin nuget:?package=EricksonLopez.Outbox.SourceGenerators&version=1.0.0
#tool nuget:?package=EricksonLopez.Outbox.SourceGenerators&version=1.0.0
EricksonLopez.Outbox
A high-performance, cloud-native, and zero-allocation oriented implementation of the Transactional Outbox and Idempotent Inbox patterns for .NET.
The Transactional Outbox pattern ensures that the creation or modification of a domain model and the publishing of the corresponding event to a Message Broker (e.g., RabbitMQ, Kafka) are performed as an atomic operation, avoiding the dreaded "Dual Write Problem".
The Idempotent Inbox pattern protects your consumers from executing business logic twice in the event that the Message Broker delivers the same message more than once (At-Least-Once Delivery).
⚡ Performance
BenchmarkDotNet v0.13.12 · .NET 10.0.10 (10.0.1026.32716) · X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI · Windows 11 (10.0.26200.8875)
Storage: InMemory (isolates framework CPU/GC overhead from network I/O). See full methodology.
vs. Industry Competitors — StoreAsync (single message)
| Method | Mean | Error | StdDev | Ratio | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|
| EricksonLopez.Outbox | 256 ns | ±1.4 ns | ±1.3 ns | 1.0× | 448 B | 1.0× |
CAP StoreAsync |
856 ns | ±7.3 ns | ±6.5 ns | 3.3× | 1,664 B | 3.7× |
NServiceBus StoreAsync |
25,424 ns | ±194 ns | ±181 ns | 99× | 5,457 B | 12.2× |
Serialization — IBufferWriter<byte> vs allocating path
| Method | Payload | Mean | Ratio | Allocated | Alloc Ratio |
|---|---|---|---|---|---|
Serialize_BufferWriter |
512 B | 54 ns | 0.68× | 32 B | 0.05× |
Serialize_Allocating |
512 B | 79 ns | 1.0× | 592 B | 1.0× |
Serialize_BufferWriter |
10 KB | 337 ns | 0.57× | 32 B | 0.003× |
Serialize_Allocating |
10 KB | 593 ns | 1.0× | 10,320 B | 1.0× |
Serialize_BufferWriter |
100 KB | 3,380 ns | 0.44× | 32 B | ~0× |
Serialize_Allocating |
100 KB | 7,767 ns | 1.0× | 102,573 B | 1.0× |
Concurrency — Parallel StoreAsync (linear scaling up to 64 threads)
| Threads | Mean | Ops/s | Allocated |
|---|---|---|---|
| 1 | 847 ns | 1,181,111 | 728 B |
| 4 | 1,546 ns | 646,999 | 2,600 B |
| 16 | 4,475 ns | 223,472 | 9,800 B |
| 64 | 9,700 ns | 103,097 | 38,601 B |
Type Resolution (FrozenDictionary — O(1) zero-alloc)
| Method | Mean | Allocated |
|---|---|---|
GetAlias |
1.37 ns | 0 B |
Resolve |
2.59 ns | 0 B |
Key takeaways:
- 3.3× faster and 73% less memory than CAP in store operations.
- 99× faster and 92% less memory than NServiceBus.
IBufferWriter<byte>serialization path allocates only 32 B regardless of payload size — a 94–99.97% memory reduction vs the allocating path.- Type resolution is zero-allocation at ~1–2 nanoseconds via
FrozenDictionary. - Scales linearly to 64 concurrent threads with zero lock contention on the store path.
→ Full benchmark results and methodology · Performance tuning guide
Key Features
- Guaranteed Atomicity: Seamless integration with ADO.NET transactions (
DbTransactionContext) and Entity Framework Core. - Extreme Performance: Optimized with
ReadOnlyMemory<T>,ValueTask, and array pooling for serialization to reduce Gen 0 garbage collection. - AOT Ready: Native support for Ahead-Of-Time (Native AOT) compilation via
System.Text.JsonSource Generators. Zero runtime reflection. - Adaptive Dispatcher: Dynamic polling that reduces frequency when there is no load (Adaptive Polling) to prevent database saturation, using
SKIP LOCKEDfor multi-instance horizontal scalability. - Circuit Breaker & Retry Policies: Robust fault tolerance strategies using
ExponentialBackoffPolicy. - Built-in Idempotency: Native de-duplication of incoming messages via the Inbox daemon.
- Broker Abstraction: Decoupled from the transport layer. Send messages to RabbitMQ, Kafka, Azure Service Bus, AWS SQS, Google Pub/Sub, NATS, or Redis Streams.
Ecosystem Packages
.NET Framework Support Policy
All library packages target net8.0, net9.0, and net10.0. Analyzers and SourceGenerators target netstandard2.0.
Support Policy: This library supports only .NET frameworks with active official support from Microsoft. A framework version is included in
TargetFrameworksas long as it appears on the Microsoft .NET Support Policy page under Active or Maintenance status. Framework versions are removed fromTargetFrameworkswhen they reach their official end-of-life date as defined by Microsoft — not before, and not after.
Framework Type Microsoft Support End Date Status .NET 8 LTS November 10, 2026 ✅ Supported .NET 9 STS November 10, 2026 ✅ Supported .NET 10 LTS November 2028 ✅ Supported
Quick Start
- Install the core package and a storage provider:
dotnet add package EricksonLopez.Outbox dotnet add package EricksonLopez.Outbox.Storage.PostgreSql - Configure services in your
Program.cs:builder.Services.AddOutbox(options => { // 1. Use Source Generators for JSON serialization options.UseSerializer(new NativeAotJsonSerializer(OutboxJsonContext.Default)); // 2. Resolve type mapping for AOT options.UseGeneratedTypes(); }); // 3. Register the Database Repository builder.Services.AddScoped<IOutboxRepository, PostgreSqlOutboxRepository>(); // 4. Start the Background Daemons builder.Services.AddOutboxDispatcher(options => { options.BatchSize = 100; options.UseAdaptivePolling = true; });
Documentation
| Topic | Link |
|---|---|
| Architecture & Flows | docs/architecture.md |
| API Reference | docs/api-reference.md |
| Cookbook & Best Practices | docs/cookbook.md |
| Progressive Tutorial | docs/showcase/ |
| Packages & Versioning | docs/packages.md |
| Compatibility Matrix | docs/compatibility-matrix.md |
| Performance & Benchmarks | docs/benchmark-results.md |
| Performance Tuning Guide | docs/performance-guide.md |
| CI/CD Pipeline | docs/ci-cd.md |
| Quality Gates | docs/quality-gates.md |
| Migration Guide | docs/migration-guide.md |
| Troubleshooting & FAQ | docs/troubleshooting.md |
| Design Decisions (ADRs) | docs/design-decisions.md |
| Comparative Analysis | docs/comparative-analysis.md |
| Repository Inventory | docs/repository-inventory.md |
Contributing
See CONTRIBUTING.md for information on building the project, running tests, and contributing guidelines.
Security
Please review SECURITY.md for details on our security policies and how to report vulnerabilities.
Code of Conduct
We follow the Contributor Covenant. See CODE_OF_CONDUCT.md for details.
License
This project is licensed under the MIT License — see the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 5.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.