ModulusKit.Messaging
4.0.0
dotnet add package ModulusKit.Messaging --version 4.0.0
NuGet\Install-Package ModulusKit.Messaging -Version 4.0.0
<PackageReference Include="ModulusKit.Messaging" Version="4.0.0" />
<PackageVersion Include="ModulusKit.Messaging" Version="4.0.0" />
<PackageReference Include="ModulusKit.Messaging" />
paket add ModulusKit.Messaging --version 4.0.0
#r "nuget: ModulusKit.Messaging, 4.0.0"
#:package ModulusKit.Messaging@4.0.0
#addin nuget:?package=ModulusKit.Messaging&version=4.0.0
#tool nuget:?package=ModulusKit.Messaging&version=4.0.0
Modulus.Messaging
Messaging library for .NET modular monoliths: integration events over an in-house transport layer with a transactional outbox and inbox. This core package includes the in-memory transport; RabbitMQ and Azure Service Bus ship as separate transport packages.
Installation
dotnet add package ModulusKit.Messaging
For a broker transport, add the matching package and register it with one line:
| Transport | Package | Registration |
|---|---|---|
| RabbitMQ | ModulusKit.Messaging.RabbitMq |
services.AddModulusRabbitMqTransport(); |
| Azure Service Bus | ModulusKit.Messaging.AzureServiceBus |
services.AddModulusAzureServiceBusTransport(); |
Setup
Bind the Messaging section from configuration — this is the section modulus init --transport
scaffolds into appsettings.json. The callback supplies the handler assemblies and any Azure
credential, which cannot be bound from configuration:
// appsettings.json
{
"Messaging": {
"Transport": "InMemory"
}
}
services.AddModulusMessaging(builder.Configuration, options =>
{
options.Assemblies.Add(typeof(Program).Assembly);
});
The callback runs after binding, so it can also override any bound value. Prefer this overload so
transport, connection string, and outbox/retry settings live in configuration. You can also
configure everything imperatively via AddModulusMessaging(Action<MessagingOptions>).
Transport Configuration
Select the transport via the Messaging section — "InMemory", "RabbitMq", or "AzureServiceBus":
{
"Messaging": {
"Transport": "RabbitMq",
"ConnectionString": "...",
"EndpointName": "orders-service",
"PrefetchCount": 10,
"AutoProvision": true
}
}
services.AddModulusRabbitMqTransport(); // from ModulusKit.Messaging.RabbitMq
services.AddModulusMessaging(builder.Configuration, options =>
{
options.Assemblies.Add(typeof(Program).Assembly);
});
The RabbitMQ connection string format is amqp://user:pass@host:5672/vhost; Azure Service Bus takes
either an Endpoint=sb://... connection string or FullyQualifiedNamespace plus a TokenCredential
set in the callback (managed identity). Keep credentials in user secrets or environment variables.
If configuration selects a broker transport whose package is not registered, the host fails at startup with guidance on which package to install.
Key options (all bindable from the Messaging section):
EndpointName— queue/subscription identity of this host; defaults to the sanitized entry assembly name. Replicas sharing it compete for messages.PrefetchCount— messages delivered ahead of acknowledgement (default 10, range 1–1000).AutoProvision— declare topology automatically (defaulttrue); setfalsewith pre-created entities for least privilege.OutboxPollInterval/OutboxBatchSize— outbox processor cadence (defaults: 5 seconds / 100).RetryPolicy:*(outbox dispatch) andConsumerRetry:*(in-process consumer retry) — independent exponential-backoff policies.
Publishing Events
public record OrderShipped(Guid OrderId, DateTime ShippedAt)
: IntegrationEvent;
// Publish directly via the message bus
await messageBus.Publish(new OrderShipped(orderId, DateTime.UtcNow));
// Or store in the outbox for reliable delivery
await outboxStore.Save(new OrderShipped(orderId, DateTime.UtcNow));
When using the outbox, events are stored as rows in the outbox table before being published. The default IOutboxStore commits through the package's own OutboxDbContext, in its own transaction — durable and broker-outage-safe, but not atomic with your business SaveChanges. For strict same-transaction atomicity, map OutboxMessage into your application DbContext (and attach OutboxNotifyingInterceptor to it) so business rows and outbox rows commit in one SaveChanges — see the outbox documentation for both setups. A background OutboxProcessor dispatches pending messages through the configured transport, retrying per RetryPolicy before dead-lettering.
Handling Events
public class OrderShippedHandler : IIntegrationEventHandler<OrderShipped>
{
public async Task Handle(OrderShipped @event, CancellationToken ct)
{
// Handle the cross-module event
}
}
Handlers are auto-discovered from the assemblies you provide in MessagingOptions.Assemblies and registered as scoped services. All registered handlers for an event type are invoked; with the inbox registered, each handler runs at most once per event.
Database setup
The outbox and inbox tables live in the OutboxDbContext and InboxDbContext that ship with this package. The package itself is provider-agnostic — you pick the EF Core provider (SQL Server, PostgreSQL, SQLite, etc.) in your host project and generate the migrations once against your chosen provider.
See Migrations/README.md in the repository for the full workflow. The short version:
builder.Services.AddModulusOutbox(o => o.UseSqlServer(connectionString));
builder.Services.AddModulusInbox(o => o.UseSqlServer(connectionString));
var app = builder.Build();
await app.UseModulusMessagingMigrationsAsync(); // applies pending migrations safely
app.Run();
Switching Transports
Switching between in-memory, RabbitMQ, and Azure Service Bus is a configuration change — flip the Messaging section's Transport value and supply the matching connection settings (with the transport package registered). No code changes are needed in your handlers or publishers.
Learn More
See the Modulus documentation for the full messaging reference, including per-transport topology and the MassTransit migration guide.
| 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 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
- Azure.Core (>= 1.47.1)
- Microsoft.EntityFrameworkCore (>= 10.0.3)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.3)
- Microsoft.Extensions.Configuration (>= 10.0.3)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Diagnostics.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Logging (>= 10.0.3)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.3)
- ModulusKit.Messaging.Abstractions (>= 4.0.0)
-
net8.0
- Azure.Core (>= 1.47.1)
- Microsoft.EntityFrameworkCore (>= 8.0.29)
- Microsoft.EntityFrameworkCore.Relational (>= 8.0.29)
- Microsoft.Extensions.Configuration (>= 10.0.3)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Diagnostics.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Logging (>= 10.0.3)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.3)
- ModulusKit.Messaging.Abstractions (>= 4.0.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on ModulusKit.Messaging:
| Package | Downloads |
|---|---|
|
ModulusKit.Messaging.RabbitMq
RabbitMQ transport for ModulusKit.Messaging, built directly on RabbitMQ.Client with fanout-exchange-per-event topology, durable endpoint queues, and dead-letter exchanges. |
|
|
ModulusKit.Messaging.AzureServiceBus
Azure Service Bus transport for ModulusKit.Messaging, built directly on Azure.Messaging.ServiceBus with topic-per-event topology and subscription-per-endpoint consumers. Requires Standard or Premium tier (topics). |
|
|
ModulusKit.Testing
Test harness, in-memory test transport, and outbox/inbox assertion helpers for ModulusKit.Messaging — module-level integration testing without hand-rolled fakes. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.0 | 157 | 7/26/2026 |
| 3.1.0 | 353 | 7/26/2026 |
| 3.0.0 | 280 | 7/26/2026 |
| 2.1.0 | 128 | 7/4/2026 |
| 2.0.0 | 133 | 7/3/2026 |
| 1.2.5 | 132 | 3/15/2026 |
| 1.2.4 | 109 | 3/15/2026 |
| 1.2.3 | 110 | 3/14/2026 |
| 1.2.2 | 110 | 3/14/2026 |
| 1.2.1 | 109 | 3/14/2026 |
| 1.2.0 | 125 | 3/14/2026 |
| 1.1.1 | 111 | 3/8/2026 |
| 1.1.0 | 111 | 3/5/2026 |
| 1.0.1 | 119 | 3/3/2026 |