Swevo.AutoBus
1.1.0
Prefix Reserved
dotnet add package Swevo.AutoBus --version 1.1.0
NuGet\Install-Package Swevo.AutoBus -Version 1.1.0
<PackageReference Include="Swevo.AutoBus" Version="1.1.0" />
<PackageVersion Include="Swevo.AutoBus" Version="1.1.0" />
<PackageReference Include="Swevo.AutoBus" />
paket add Swevo.AutoBus --version 1.1.0
#r "nuget: Swevo.AutoBus, 1.1.0"
#:package Swevo.AutoBus@1.1.0
#addin nuget:?package=Swevo.AutoBus&version=1.1.0
#tool nuget:?package=Swevo.AutoBus&version=1.1.0
AutoBus
Free, MIT-licensed message bus for .NET. No commercial license required — ever.
Why AutoBus?
MassTransit v9 is now a commercial product. AutoBus is a much smaller, focused alternative for the common case: a modular monolith (or a small set of services) that wants reliable pub/sub and point-to-point messaging with retry, without adopting a paid distributed messaging framework. It isn't a drop-in MassTransit replacement — there's no saga state machine engine, no routing slips, no multi-broker rider abstraction — just consumers, publish/send, retry, and (optionally) RabbitMQ.
public sealed class OrderCreated
{
public int OrderId { get; init; }
}
public sealed class SendWelcomeEmail : IConsumer<OrderCreated>
{
public Task Consume(ConsumeContext<OrderCreated> context)
{
// send the email...
return Task.CompletedTask;
}
}
services.AddAutoBus(cfg => cfg.AddConsumer<SendWelcomeEmail>());
// elsewhere:
await messageBus.PublishAsync(new OrderCreated { OrderId = 42 });
Install
dotnet add package Swevo.AutoBus
For cross-process messaging over RabbitMQ:
dotnet add package Swevo.AutoBus.RabbitMQ
Core concepts
IConsumer<TMessage>— implement this for each message type you handle.IMessageBus.PublishAsync— fan-out to every registered consumer for a message type (zero consumers is not an error).IMessageBus.SendAsync— point-to-point; throws if zero or more than one consumer is registered for the message type.IRequestClient<TRequest, TResponse>— sends a request to exactly oneIRequestHandler<TRequest, TResponse>and awaits its correlated response.- Retry — every consumer invocation runs through a Polly retry pipeline (exponential
backoff, 3 attempts by default). Configure with
cfg.UseRetry(retryCount, baseDelay). - Transports —
InMemoryTransport(default, in-process dispatch) orRabbitMqTransport/RabbitMqConsumerHost(cross-process, viaSwevo.AutoBus.RabbitMQ).
RabbitMQ transport
services.AddAutoBus(cfg => cfg.AddConsumer<SendWelcomeEmail>());
services.AddAutoBusRabbitMq(options =>
{
options.HostName = "localhost";
options.QueuePrefix = "orders-service"; // scopes queue names per service
});
Publishing a message sends it to a fanout exchange named after the message's full type name.
AddAutoBusRabbitMq also registers a hosted RabbitMqConsumerHost that declares and binds a
durable queue for every locally-registered consumer, so the same IConsumer<T> code runs
whether messages arrive in-process or over the broker — call AddAutoBusRabbitMq after
AddAutoBus since it replaces the default in-memory transport.
Request/Response
If you're migrating from MassTransit, AutoBus now supports the familiar "send a request and await a correlated reply" pattern for in-process modular-monolith calls:
public sealed record GetOrderStatus(int OrderId);
public sealed record OrderStatus(string Value);
public sealed class GetOrderStatusHandler : IRequestHandler<GetOrderStatus, OrderStatus>
{
public Task<OrderStatus> Consume(ConsumeContext<GetOrderStatus> context)
=> Task.FromResult(new OrderStatus($"Order {context.Message.OrderId} is ready"));
}
services.AddAutoBus(cfg =>
{
cfg.AddRequestHandler<GetOrderStatusHandler>();
cfg.UseRequestTimeout(TimeSpan.FromSeconds(10)); // optional, default is 30s
});
var client = serviceProvider.GetRequiredService<IRequestClient<GetOrderStatus, OrderStatus>>();
var response = await client.GetResponseAsync(new GetOrderStatus(42));
Conceptually this is similar to MassTransit's IRequestClient<TRequest>.GetResponse<TResponse>(),
but AutoBus keeps it intentionally small:
- In-process only. Request/response uses an in-memory correlation registry and local handler dispatch; it is not a distributed RPC abstraction across RabbitMQ or other transports.
- Exactly one handler.
GetResponseAsyncthrows if zero or more than one matchingIRequestHandler<TRequest, TResponse>is registered. - Same retry pipeline. Request handlers execute through the same Polly-backed retry pipeline
as regular
IConsumer<T>deliveries. - Correlated replies. Every request gets a correlation ID exposed as
ConsumeContext<TRequest>.CorrelationId. - Clear timeout behavior. If no response arrives before the effective timeout, AutoBus throws
RequestTimeoutException.
Using AutoBus from an EF Core transactional outbox
AutoBus's IMessageBus.PublishAsync(object message, Type messageType, CancellationToken)
overload mirrors MassTransit's IPublishEndpoint.Publish(object, Type, CancellationToken)
signature, so it's a drop-in replacement inside an outbox processor loop — see
EFCore.Outbox, which uses AutoBus instead of
MassTransit for exactly this reason.
Design goals
- MIT licensed, forever. No commercial tier, no per-seat fees.
- Small surface area. Consumers, publish/send, retry — no bespoke DSL to learn.
- Same code, two transports. Consumers are written once; swapping
InMemoryTransportforRabbitMqTransportis a one-line DI change.
Roadmap
- Saga/state-machine support and additional broker transports (Azure Service Bus, Amazon SQS) are being considered for future releases, scoped to real demand rather than parity with MassTransit's full feature set.
💼 Need .NET consulting?
I'm the author of AutoBus and a suite of compile-time source generators (AutoWire, AutoMap.Generator) and 28+ Polly v8 resilience packages. I'm available for consulting on Polly v8 resilience, Azure cloud architecture, and clean .NET design.
→ solidqualitysolutions.com · LinkedIn
Also by the same author
🌐 Full suite overview: swevo.github.io
| Package | Description |
|---|---|
| FluentPdf | Free, MIT-licensed fluent PDF generation — alternative to QuestPDF's commercial license. |
| AutoArchitecture | Free, MIT-licensed compile-time architecture rule enforcement — alternative to NDepend. |
| EFCore.Outbox | Transactional outbox pattern for EF Core — pairs naturally with AutoBus. |
| Swevo.AutoAssert | Free, MIT-licensed fluent assertions — alternative to FluentAssertions' commercial license. |
| EFCore.BulkOperations | Free, MIT-licensed bulk insert/update/delete for EF Core. |
| AutoWire | Compile-time DI auto-registration — [Scoped]/[Singleton]/[Transient] generates IServiceCollection registration code. |
| AutoDispatch.Generator | Compile-time CQRS dispatcher — free alternative to MediatR's commercial license. |
| PollyAnalyzers | Free Roslyn analyzers for async/resilience anti-patterns — blocking calls, async void, fire-and-forget tasks, swallowed exceptions. |
| PollyAction | Free retry/backoff GitHub Action — wrap any CI step with exponential-backoff retries. |
License
MIT © Justin Bannister
| 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. |
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
- Polly.Core (>= 8.7.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Swevo.AutoBus:
| Package | Downloads |
|---|---|
|
Swevo.EFCore.Outbox
Transactional outbox pattern for EF Core + AutoBus. Add outbox messages atomically with your domain changes via a SaveChangesInterceptor, then publish them reliably via a background processor. Zero message loss even if the bus is unavailable at save time. |
|
|
Swevo.AutoBus.RabbitMQ
RabbitMQ transport for AutoBus. Publishes messages to a fanout exchange per message type and hosts a background consumer that binds a durable queue for every registered AutoBus consumer, so the same IConsumer<T>/IMessageBus programming model works across process boundaries. |
GitHub repositories
This package is not used by any popular GitHub repositories.
1.1.0: Add in-process request/response messaging via IRequestClient<TRequest, TResponse> and IRequestHandler<TRequest, TResponse> with correlated replies, configurable timeout handling, and retry-backed handler execution. 1.0.1: Add missing package icon. 1.0.0: Initial release. IConsumer<T>, IMessageBus (Publish/Send), in-memory transport, Polly retry, DI registration.