AxisBus 2.2.0
dotnet add package AxisBus --version 2.2.0
NuGet\Install-Package AxisBus -Version 2.2.0
<PackageReference Include="AxisBus" Version="2.2.0" />
<PackageVersion Include="AxisBus" Version="2.2.0" />
<PackageReference Include="AxisBus" />
paket add AxisBus --version 2.2.0
#r "nuget: AxisBus, 2.2.0"
#:package AxisBus@2.2.0
#addin nuget:?package=AxisBus&version=2.2.0
#tool nuget:?package=AxisBus&version=2.2.0
AxisBus — Documentation
A one-method event bus port — IAxisBus.PublishAsync<TEvent>(@event, params topics) returning an AxisResult that aggregates every handler failure. Drop in AxisMemoryBus for in-process broadcasting; swap it for a Kafka, RabbitMQ, Service Bus or transactional-outbox adapter without touching application code.
public Task<AxisResult<CreateOrderResponse>> HandleAsync(CreateOrderCommand cmd)
=> orderFactory.CreateAsync(cmd)
.ThenAsync(order => bus.PublishAsync(new OrderCreatedEvent(order.OrderId))) // enqueue in the outbox…
.ThenAsync(order => unitOfWork.SaveChangesAsync()) // …then one commit persists the order AND the event
.MapAsync(order => new CreateOrderResponse { OrderId = order.OrderId });
The event never leaves the unit of work. With an outbox adapter (see Custom adapter),
PublishAsyncenqueues the event on the unit of work's connection before the commit — the singleSaveChangesAsyncthen persists the state change and the event together, atomically, or neither. There is no commit-then-publish dual-write, so the classic race — state committed but the event lost, or the event broadcast for a state change that then rolls back — cannot happen. In-memory fan-out for tolerant side effects (cache, email) is a separate role → seePublishAsync.
Use this page as a map: read the trunk below (~5 min) and jump straight to the detail of the group you need — without reading hundreds of lines.
The trunk (read first)
The interface in 60 seconds
public interface IAxisBus
{
Task<AxisResult> PublishAsync<TEvent>(TEvent @event, params string[] topics)
where TEvent : IAxisEvent;
}
One method. The bus fans the event out to every registered IAxisEventHandler<TEvent>, runs them in parallel, and aggregates the results with AxisResult.Combine — every handler's errors are surfaced together. Routing details (topics, partition keys, exchanges) are the adapter's problem, not the caller's. → The IAxisBus contract
Events and handlers
The contracts come from AxisMediator:
public interface IAxisEvent
{
string? OrderingKey => null; // optional; the durable outbox's FIFO partition key
}
public interface IAxisEventHandler<in TEvent> where TEvent : IAxisEvent
{
Task<AxisResult> HandleAsync(TEvent @event);
}
Define a record that implements IAxisEvent, write a handler for it, register it in DI, and the bus picks it up. → Defining events and handlers
In-memory adapter
AxisMemoryBus registers IAxisBus against in-process handlers, runs them in parallel and aggregates their results:
services.AddAxisMemoryBus(); // wires IAxisBus → MemoryBusAdapter + scans for handlers
Durable outbox adapter (bundled)
AxisBus.Repository ships a production-ready transactional outbox over Postgres/MySQL: publishing enqueues on the unit of work, a commit drains it atomically with the business state, and a background dispatcher delivers it after the commit — no status column, claim-by-lease, at-least-once:
services.AddAxisBusPostgres(new AxisBusRepositorySettings { ConnectionString = "..." }); // or AddAxisBusMySql
→ API reference (see "Durable outbox adapter")
Installation
dotnet add package AxisBus # the abstraction (depends on AxisResult)
dotnet add package AxisMemoryBus # in-process adapter
→ Full guide: Getting started
The map (jump to what you need)
| Group | You want to… | Detail |
|---|---|---|
Contract · IAxisBus |
the publishing port and its semantics | iaxisbus.md |
Publish · PublishAsync ⭐ |
fan-out an event to every handler | publish.md |
Events · IAxisEvent |
define events and write handlers | events-and-handlers.md |
In-process · AxisMemoryBus |
the ready-made adapter | memory-adapter.md |
Durable outbox · AxisBus.Repository |
the bundled transactional-outbox adapter (Postgres/MySQL) | api-reference.md |
| Custom adapter | write your own (Kafka, RabbitMQ, Service Bus) | custom-adapter.md |
| Why? | the case for a one-method port | why-axisbus.md |
| Reference | every member at a glance | api-reference.md |
Start here: Getting started · The IAxisBus contract · Why AxisBus?
Fundamentals: Publish · PublishAsync · Defining events and handlers · AxisMemoryBus adapter
Reference & extras: Custom adapter · API reference
Design principles
- One method. A publish-only port keeps the application out of the transport's vocabulary. Subscriptions live in the adapter or the broker, not in the abstraction.
- Errors aggregate, not crash. Every handler's failure becomes an entry in the combined
AxisResult. The publisher sees the whole picture, not the first thing that blew up. - Handlers run in parallel. The in-memory adapter awaits all handlers concurrently. Side effects must be independent.
- Routing belongs to the adapter. Topics, partition keys and exchanges are vendor concepts. The port accepts a
params string[] topicsso callers can hint, but interpretation is the adapter's call. - Events are dumb records.
IAxisEventis a marker interface. Add the fields the consumers need; nothing more. - Domain events ride the unit of work. A domain event is staged inside the transaction that persists the state change — an outbox adapter writes the event row on the same connection, and the commit makes both durable atomically. Never
SaveChangesfirst andPublishafter: that dual-write can commit the state while losing the event. In-memory fan-out is reserved for post-commit side effects that tolerate loss.
License
Apache 2.0
| 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
- AxisMediator.Contracts (>= 2.2.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on AxisBus:
| Package | Downloads |
|---|---|
|
AxisBus.Repository
Part of the Axis Framework — an opinionated, ports-and-adapters .NET framework. |
|
|
AxisMemoryBus
Part of the Axis Framework — an opinionated, ports-and-adapters .NET framework. |
GitHub repositories
This package is not used by any popular GitHub repositories.