NuGet NuGet Downloads CI License: MIT .NET 10 Ready
Free, MIT-licensed message bus for .NET. No commercial license required — ever.
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 });
dotnet add package Swevo.AutoBus
For cross-process messaging over RabbitMQ:
dotnet add package Swevo.AutoBus.RabbitMQ
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).
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.
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.
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.
- 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.
- 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.
| Package | Downloads | Description |
|---|---|---|
| Swevo.AutoAssert | Downloads | Free, MIT-licensed fluent assertions for |
| Swevo.AutoAuth | Downloads | A free, MIT-licensed fluent configuration wrapper around OpenIddict for building OAuth2/OIDC token servers in ASP |
| Swevo.AutoAudit | Downloads | Compile-time audit field generation for EF Core entities using Roslyn source generators |
| Swevo.AutoResult | Downloads | Compile-time Result monad for |
| Swevo.AutoGuard | Downloads | Compile-time guard clauses for |
| Swevo.AutoImage | Downloads | A free, MIT-licensed fluent image processing wrapper around SkiaSharp for |
| Swevo.AutoFeatureFlag | Downloads | Compile-time feature flag stubs for |
| Swevo.AutoTestData | Downloads | Compile-time test data builders for |
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
🌐 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. |
MIT © Justin Bannister