Skip to content

Swevo/AutoBus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AutoBus

NuGet NuGet Downloads CI License: MIT

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 one IRequestHandler<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).
  • TransportsInMemoryTransport (default, in-process dispatch) or RabbitMqTransport/RabbitMqConsumerHost (cross-process, via Swevo.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. GetResponseAsync throws if zero or more than one matching IRequestHandler<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 InMemoryTransport for RabbitMqTransport is 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.

Related Packages

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

💼 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

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages