Rig.TUnit.Messaging
0.1.0-beta.2
dotnet add package Rig.TUnit.Messaging --version 0.1.0-beta.2
NuGet\Install-Package Rig.TUnit.Messaging -Version 0.1.0-beta.2
<PackageReference Include="Rig.TUnit.Messaging" Version="0.1.0-beta.2" />
<PackageVersion Include="Rig.TUnit.Messaging" Version="0.1.0-beta.2" />
<PackageReference Include="Rig.TUnit.Messaging" />
paket add Rig.TUnit.Messaging --version 0.1.0-beta.2
#r "nuget: Rig.TUnit.Messaging, 0.1.0-beta.2"
#:package Rig.TUnit.Messaging@0.1.0-beta.2
#addin nuget:?package=Rig.TUnit.Messaging&version=0.1.0-beta.2&prerelease
#tool nuget:?package=Rig.TUnit.Messaging&version=0.1.0-beta.2&prerelease
Rig.TUnit.Messaging
Messaging family-base:
MessagingRigBuilder<TSelf>,ListenerBase<T>,EventSenderBase(correlation / causation / W3C traceparent),MessageAssert,DeadLetterAssert,OrderingAssert,TopicNamingConvention.
What this package is
The shared contract for every messaging provider (.Kafka, .Nats,
.RabbitMq, .ServiceBus, .Sqs). Defines:
- Listener lifecycle —
ListenerBase<T>(start/stop, capture). - Sender side —
EventSenderBasewith automatic correlation/causation/W3Ctraceparentinjection. - Cross-provider routing keys —
SendContext(SessionKey, PartitionKey, DeduplicationKey)carries the per-message ordering / partitioning / idempotency hints that each provider maps to its native primitive (Service BusSessionId, KafkaMessage.Key, SQSMessageGroupId, RabbitMQ routing key, NATS JetStream subject). - Topology builder marker —
ITopologyBuilderis the application hook every provider'sWithTopology(…)lambda returns. The base interface carries no fluent methods; provider packages own their own typed surface so calling.Queue()on Kafka or.WithFifo()on RabbitMQ is a compile error, not a runtime no-op. - Captured envelope —
CapturedMessage<TMessage>records the raw message, headers, body, correlation ID, and (for session-aware listeners) the per-session ordering key. - Assertion families —
MessageAssert(payload shape),DeadLetterAssert(DLQ content after N retries),OrderingAssert(strict FIFO, partition-ordered, or best-effort).
TopicNamingConvention enforces the {company}-{domain}-{side} naming
so cross-service traces line up in Seq / OpenTelemetry.
Install one of the leaves directly.
When to use it
- Authoring a new messaging backend.
- Writing provider-agnostic messaging helpers.
- Not for: concrete messaging — install a leaf package.
Prerequisites
- .NET 10 SDK
Quick start
using Rig.TUnit.Core.Builder;
using Rig.TUnit.Core.Helpers;
using Rig.TUnit.Messaging.Helpers;
var rig = new RigBuilder()
.WithIsolation(IsolationKey.FromExecutionContext())
.Build();
await using var _ = rig;
// SendContext carries cross-provider routing keys to any *EventSender.SendAsync overload.
var ctx = new SendContext(
SessionKey: "order-42", // Service Bus SessionId · SQS MessageGroupId · NATS x-session-key
PartitionKey: "order-42", // Kafka Message.Key · RabbitMQ routing key
DeduplicationKey: "evt-123"); // Service Bus MessageId · SQS MessageDeduplicationId
Provider-specific WithTopology(…) hooks (returning a typed
ITopologyBuilder subtype) live on each provider's RigBuilder —
ServiceBusRigBuilder.WithTopology(Action<IServiceBusTopologyBuilder>),
KafkaRigBuilder.WithTopology(Action<IKafkaTopologyBuilder>), etc.
Options
| Property | Type | Default | Description |
|---|---|---|---|
DefaultMessageTtl |
TimeSpan |
5m |
Applied when the backend supports per-message TTL |
MaxRetryAttempts |
int |
5 |
Before dead-lettering |
CorrelationHeader |
string |
"X-Correlation-Id" |
HTTP-compatible header name |
TracePropagation |
bool |
true |
Inject W3C traceparent on send |
Fixture + helper APIs
Rig.TUnit.Messaging.IMessagingRigRig.TUnit.Messaging.Fixtures.MessagingFixtureBaseRig.TUnit.Messaging.Builder.MessagingRigBuilder<TSelf>— note: by design (per ADR / NFR-C3) the base does not declareWithTopology; each provider'sRigBuilderadds the strongly-typed hook.Rig.TUnit.Messaging.Helpers.ListenerBase<T>+CapturedMessage<T>Rig.TUnit.Messaging.Helpers.EventSenderBaseRig.TUnit.Messaging.Helpers.SendContext— record carryingSessionKey/PartitionKey/DeduplicationKey.Rig.TUnit.Messaging.Topology.ITopologyBuilder— marker; declares onlyTask ApplyAsync(CancellationToken).Rig.TUnit.Messaging.Assertions.MessageAssertRig.TUnit.Messaging.Assertions.DeadLetterAssertRig.TUnit.Messaging.Assertions.OrderingAssertRig.TUnit.Messaging.Helpers.TopicNamingConvention
Per-test isolation
Each leaf names topics/queues with {IsolationKey} so parallel tests
do not collide. Teardown deletes the per-test queue/topic.
Parallelism + performance
§9 — N/A: family-base; per-provider. Kafka bind-port constrains
parallelism; ServiceBus / SQS are effectively unbounded.
Troubleshooting
traceparentheader missing on received message — the sender is bypassingEventSenderBase(using the raw SDK client). Always route through the Rig sender for consistent propagation.
Provider quirks + edge cases
- Ordering guarantees differ: Kafka partition-ordered, ServiceBus session-ordered, SQS FIFO queues exact-ordered, RabbitMQ per-queue, NATS best-effort (core) / per-stream-subject (JetStream).
SendContextdoes not invent semantics on providers that lack them.DeduplicationKeyis honoured only by Service Bus (with duplicate detection enabled on the entity) and SQS FIFO; Kafka / RabbitMQ / NATS ignore it.- Topology builders are provider-scoped, compile-time-enforced:
there is no shared
ITopologyBuilder.Queue(...)to throw on. The presence test (ProviderCompletenessTests) only asserts that every provider listed intests/Rig.TUnit.Architecture.Tests/.parity-coverage.txtships aWithTopologyhook returning someITopologyBuilder; the exact surface is each provider's choice. - Idempotent apply: every provider's
ApplyAsyncis create-or-update, so running the same topology twice (or against an already-provisioned broker) succeeds without throwing.
Benchmarks
§12 — N/A: family-base; concrete leaves have individual
*Benchmarks.cs entries under tests/Rig.TUnit.Benchmarks/.
Related docs
- Architecture diagram
- ADR-005 — family-level contracts
- Glossary
- Ordering assertions — capability matrix
- Per-provider topology + sessions docs:
docs/providers/(service-bus.md · kafka.md · rabbitmq.md · sqs.md · nats.md) - Feature design: Sessions & Partitions Design · Topology Builder Design
License
MIT. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Bogus (>= 35.6.1)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- Rig.TUnit.Core (>= 0.1.0-beta.2)
- TUnit.Core (>= 1.34.5)
NuGet packages (7)
Showing the top 5 NuGet packages that depend on Rig.TUnit.Messaging:
| Package | Downloads |
|---|---|
|
Rig.TUnit.Messaging.RabbitMq
TUnit fixture for RabbitMQ backed by Testcontainers. Routing keys, exchanges, bindings, and per-key ordering assertions. |
|
|
Rig.TUnit.Microservices.Outbox
TUnit fixture for the transactional outbox pattern - visibility-timeout helpers, dispatcher assertions, and dedup checks. |
|
|
Rig.TUnit.Messaging.ServiceBus
TUnit fixture for Azure Service Bus backed by Testcontainers. Native sessions, deduplication, partition keys, and runtime topology builder for topics, subscriptions, and rules. |
|
|
Rig.TUnit.All
Meta-package containing every Rig.TUnit.* package. DISCOURAGED — prefer per-feature or per-stack meta-packages (Rig.TUnit, Rig.TUnit.Microservices). |
|
|
Rig.TUnit.Messaging.Kafka
TUnit fixture for Apache Kafka backed by Testcontainers. Per-key partition affinity, runtime topology builder, and per-partition offset snapshot utilities. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-beta.2 | 57 | 4/27/2026 |
| 0.0.0-alpha.0.14 | 61 | 4/26/2026 |