Akaule.NimBus.MessageStore.SqlServer 3.0.0

dotnet add package Akaule.NimBus.MessageStore.SqlServer --version 3.0.0
                    
NuGet\Install-Package Akaule.NimBus.MessageStore.SqlServer -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Akaule.NimBus.MessageStore.SqlServer" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Akaule.NimBus.MessageStore.SqlServer" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Akaule.NimBus.MessageStore.SqlServer" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Akaule.NimBus.MessageStore.SqlServer --version 3.0.0
                    
#r "nuget: Akaule.NimBus.MessageStore.SqlServer, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Akaule.NimBus.MessageStore.SqlServer@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Akaule.NimBus.MessageStore.SqlServer&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Akaule.NimBus.MessageStore.SqlServer&version=3.0.0
                    
Install as a Cake Tool

NimBus

NimBus

A nimbus for your Azure cloud — ordered, audited, and always accounted for.

NimBus is an Azure Service Bus based integration platform with a shared SDK, management web app, and message tracking and storage.

Repository Layout

  • src/NimBus.sln builds the full platform, including the web app, resolver, app host, and shared libraries.

Key projects:

  • src/NimBus.Abstractions: core interfaces (IMessage, ISender, IEventHandler, message context).
  • src/NimBus.Core: shared endpoint, event, message, and pipeline abstractions.
  • src/NimBus: platform configuration and built-in endpoint definitions.
  • src/NimBus.CommandLine: nb CLI for Azure infrastructure, topology provisioning, and deployment.
  • src/NimBus.SDK: publisher/subscriber SDK surface.
  • src/NimBus.ServiceBus: Service Bus integration layer.
  • src/NimBus.MessageStore.Abstractions: provider-neutral storage contracts (IMessageTrackingStore, ISubscriptionStore, IEndpointMetadataStore, IMetricsStore).
  • src/NimBus.MessageStore.CosmosDb: Cosmos DB storage provider.
  • src/NimBus.MessageStore.SqlServer: SQL Server storage provider (DbUp-managed schema).
  • src/NimBus.Manager / src/NimBus.Management.ServiceBus: management client abstractions and Service Bus management operations used by the web app.
  • src/NimBus.WebApp: ASP.NET Core management UI plus the React/Vite client app.
  • src/NimBus.Resolver: tracks message outcomes and updates resolver state.
  • src/NimBus.AppHost / src/NimBus.ServiceDefaults: Aspire host and shared defaults for local orchestration.
  • src/NimBus.Testing: in-memory transport plus the storage conformance suite that all message-store providers run against.
  • src/NimBus.Outbox.SqlServer: SQL Server transactional outbox implementation.
  • src/NimBus.Inbox.SqlServer: SQL Server consumer inbox implementation.

Samples live under samples/:

  • samples/AspirePubSub/: minimal publisher, subscriber (with middleware + DeferredProcessor), provisioner, and resolver worker.
  • samples/CrmErpDemo/: two-system CRM ↔ ERP integration demo — see the CRM/ERP sample section below.

Message Store

The audit trail, resolver state, blocked sessions, and metrics live behind the contracts in NimBus.MessageStore.Abstractions and are pluggable across providers. Pick the one that fits your environment; both pass the same NimBus.Testing conformance suite.

Provider Project Registration Notes
SQL Server NimBus.MessageStore.SqlServer services.AddSqlServerMessageStore(...) Schema is owned and migrated by DbUp on first run. Ships the nimbus.Messages, UnresolvedEvents, MessageAudits, EndpointSubscriptions, EndpointMetadata, Heartbeats, BlockedMessages, InvalidMessages tables plus metrics views.
Cosmos DB NimBus.MessageStore.CosmosDb services.AddCosmosDbMessageStore(...) Per-endpoint containers (see ADR-008).

The Aspire AppHost and the CRM/ERP demo both default to SQL Server and accept --StorageProvider cosmos to switch. The transactional outbox (NimBus.Outbox.SqlServer) is independent of the message-store choice.

Transport

Azure Service Bus is NimBus's transport. The platform leans on Service Bus's native primitives (sessions, deferred messages, scheduled enqueue, forwarding subscriptions, dead-letter queues) rather than abstracting them away.

Provider Project Registration Notes
Azure Service Bus NimBus.ServiceBus services.AddNimBus(b => b.AddServiceBusTransport(...)) Native sessions, deferred messages, scheduled enqueue, forwarding subscriptions, dead-letter queue.

Extensions

NimBus uses an extension framework to separate core messaging from optional features. Extensions are registered through the AddNimBus() builder and can hook into the message pipeline and lifecycle events.

  • src/NimBus.Extensions.Notifications: sends notifications on message failures and dead-letters.

See docs/extensions.md for the full guide on using and creating extensions.

Building an Adapter

A NimBus adapter is a worker process that sits between an external system and the event bus — it subscribes to events from other systems, publishes events when its own backing system changes, or both. Most consumers of NimBus are writing adapters.

Four questions decide how the wiring looks:

  1. Subscribe, publish, or both? Subscribers register handlers via AddNimBusSubscriber + AddNimBusReceiver. Publishers register AddNimBusPublisher.
  2. Long-running Worker or Azure Functions? Worker = simple, in-process, easy to debug (samples/CrmErpDemo/Crm.Adapter). Functions = serverless, native session triggers (samples/CrmErpDemo/Erp.Adapter.Functions).
  3. Direct publish or SQL Server outbox? Direct = stateless. Outbox = atomic with local DB writes via AddNimBusSqlServerOutbox.
  4. Aspire or manual ServiceBusClient? builder.AddAzureServiceBusClient("servicebus") for Aspire; manual AddSingleton<ServiceBusClient> for Functions and other hosts.

The minimum viable subscriber is small — IDeferredMessageProcessor is auto-registered by AddNimBusSubscriber, so the floor really is this:

var builder = Host.CreateApplicationBuilder(args);
builder.AddServiceDefaults();
builder.AddAzureServiceBusClient("servicebus");

builder.Services.AddNimBusSubscriber("BillingEndpoint", sub =>
{
    sub.AddHandlersFromAssemblyContaining<OrderPlacedHandler>();
});

builder.Services.AddNimBusReceiver(opts =>
{
    opts.TopicName = "BillingEndpoint";
    opts.SubscriptionName = "BillingEndpoint";
});

builder.Build().Run();

Add builder.Services.AddNimBus(n => n.AddPipelineBehavior<LoggingMiddleware>()) when you want middleware in the pipeline. Use sub.AddHandler<OrderPlaced, OrderPlacedHandler>() when you want to register or override a handler explicitly.

Next steps:

  • Building Adapters — full guide: publisher, subscriber, middleware (built-in + custom), retry policies, outbox, hosting choice
  • Getting Started — end-to-end tutorial including Aspire local dev
  • SDK API ReferenceIPublisherClient, IEventHandler<T>, RetryPolicy, IOutbox, request/response

NuGet Packages

Package Description
NimBus.Abstractions Core abstractions and interfaces
NimBus.Core Endpoint management, retry policies, logging
NimBus.ServiceBus Azure Service Bus integration
NimBus.SDK Publisher/subscriber SDK
NimBus.CommandLine nb CLI tool

Install

Packages publish under the Akaule.NimBus.* prefix (the bare NimBus.* prefix is reserved on nuget.org); assemblies and namespaces stay NimBus.*:

dotnet add package Akaule.NimBus.SDK
dotnet tool install -g Akaule.NimBus.CommandLine

Publishing

Push a version tag to trigger the NuGet publish workflow:

git tag v1.0.0
git push origin v1.0.0

Pre-release versions are supported (e.g. v1.0.0-preview.1).

Prerequisites

  • .NET 10 SDK preview, matching the project target frameworks.
  • Node.js 22+ (LTS), required by src/NimBus.WebApp/ClientApp and the samples/CrmErpDemo/Crm.Web / Erp.Web SPAs during build. Vite 8 and Vitest 4 are the minimum supported toolchain; older Node versions will fail at npm install.
  • Access to NuGet package sources used by the solution.

Build

From the repository root:

dotnet build .\src\NimBus.CommandLine\NimBus.CommandLine.csproj
dotnet build .\src\NimBus.sln

Notes:

  • src/NimBus.WebApp runs npm install and npm run build as part of the .NET build.
  • NSwag.MSBuild is used directly from NuGet; no local dotnet-tools.json manifest is required.

CLI

The repository includes a dotnet tool named nb in src/NimBus.CommandLine. It handles Azure infrastructure provisioning, Service Bus topology setup, and application deployment.

Prerequisites

  • Azure CLI (az) ≥ 2.60.0 installed and on PATH (required for Flex Consumption deploys; see docs/deployment.md)
  • az login completed for the target subscription
  • Permissions to create and deploy resources in the target resource group

Running the tool

Run via dotnet run from the repository root:

dotnet run --project .\src\NimBus.CommandLine -- <command> [options]

Alternatively, install it as a local dotnet tool:

dotnet pack .\src\NimBus.CommandLine
dotnet tool install --global --add-source .\src\NimBus.CommandLine\nupkg Akaule.NimBus.CommandLine
nb <command> [options]

Use --help on any command to see all available options:

dotnet run --project .\src\NimBus.CommandLine -- --help
dotnet run --project .\src\NimBus.CommandLine -- infra apply --help

Quick start: full deployment

To provision infrastructure, set up the Service Bus topology, and deploy the applications in one step:

dotnet run --project .\src\NimBus.CommandLine -- setup `
  --solution-id nimbus `
  --environment dev `
  --resource-group rg-nimbus-dev

This runs infra apply, topology apply, and deploy apps in sequence.

Or npx-style from a fresh clone, without building anything first (dnx ships with the .NET 10 SDK):

git clone https://github.com/akakaule/NimBus; cd NimBus
dnx Akaule.NimBus.CommandLine -- setup --solution-id nimbus --environment dev --resource-group rg-nimbus-dev

New deployments default to the cheapest sensible hosting: the resolver runs on a Flex Consumption plan (FC1, scales to zero) and the management WebApp plan is B1 for dev/development (S1 for other environments). Existing deployments keep their current plans on re-runs; see --resolver-plan and --management-plan-sku in docs/cli.md.

Commands

infra apply

Deploys Azure infrastructure (Service Bus namespace, Cosmos DB, Application Insights, Function App, Web App) using the bicep templates in deploy/bicep/.

dotnet run --project .\src\NimBus.CommandLine -- infra apply `
  --solution-id nimbus `
  --environment dev `
  --resource-group rg-nimbus-dev
Option Required Description
--solution-id <ID> Yes Identifier used in Azure resource names
--environment <NAME> Yes Environment name (e.g. dev, test, prod)
--resource-group <NAME> Yes Azure resource group to deploy into
--repo-root <PATH> No Repository root; auto-detected if omitted
--location <AZURE-REGION> No Azure region override for the bicep templates
--webapp-version <VALUE> No Version string stored in the web app settings
topology export

Exports the current PlatformConfiguration (endpoints, event types, routing) to a JSON file for inspection.

dotnet run --project .\src\NimBus.CommandLine -- topology export
dotnet run --project .\src\NimBus.CommandLine -- topology export -o .\my-config.json
Option Required Description
-o, --output <PATH> No Output path; defaults to platform-config.json in the current directory
topology apply

Provisions Service Bus topics, subscriptions, and routing rules based on PlatformConfiguration. This creates the messaging topology that the platform endpoints use to communicate.

dotnet run --project .\src\NimBus.CommandLine -- topology apply `
  --solution-id nimbus `
  --environment dev `
  --resource-group rg-nimbus-dev
Option Required Description
--solution-id <ID> Yes Solution identifier
--environment <NAME> Yes Environment name
--resource-group <NAME> Yes Resource group containing the Service Bus namespace
deploy apps

Builds, packages, and deploys the Resolver (Azure Function App) and Web App to Azure.

dotnet run --project .\src\NimBus.CommandLine -- deploy apps `
  --solution-id nimbus `
  --environment dev `
  --resource-group rg-nimbus-dev
Option Required Description
--solution-id <ID> Yes Solution identifier
--environment <NAME> Yes Environment name
--resource-group <NAME> Yes Resource group containing the target apps
--repo-root <PATH> No Repository root; auto-detected if omitted
--configuration <NAME> No Build configuration passed to dotnet publish; defaults to Release
setup

Runs the full provisioning and deployment pipeline in sequence: infra applytopology applydeploy apps. Accepts all options from those individual commands.

Resource naming

The --solution-id and --environment values are normalized (lowercased, non-alphanumeric characters removed) and combined to produce Azure resource names:

Resource Naming pattern Example
Service Bus namespace sb-{solutionId}-{environment} sb-nimbus-dev
Application Insights ai-{solutionId}-{environment}-global-tracelog ai-nimbus-dev-global-tracelog
Cosmos DB account cosmos-{solutionId}-{environment} cosmos-nimbus-dev
Resolver Function App func-{solutionId}-{environment}-resolver func-nimbus-dev-resolver
Management Web App webapp-{solutionId}-{environment}-management webapp-nimbus-dev-management

Local Development (Aspire)

The Aspire AppHost orchestrates the full platform locally. A built-in Provisioner creates the Service Bus topics/subscriptions before starting the Resolver and WebApp.

1. Set connection strings

dotnet user-secrets set "ConnectionStrings:servicebus" "<your-servicebus-connection-string>" `
  --project .\src\NimBus.AppHost

dotnet user-secrets set "ConnectionStrings:cosmos" "<your-cosmos-connection-string>" `
  --project .\src\NimBus.AppHost

2. Run

dotnet run --project .\src\NimBus.AppHost

The Aspire dashboard opens automatically. You'll see:

  • provisioner — provisions Service Bus topology, then exits
  • resolver — starts after provisioner completes
  • webapp — starts after provisioner completes (external HTTP endpoint)
  • publisher — sample HTTP API (POST /publish/order, POST /publish/order-failed)
  • subscriber — sample event handler with middleware pipeline and separated DeferredProcessor

CRM/ERP integration sample

samples/CrmErpDemo/ is a larger, two-system reference scenario: a CRM and an ERP, each with its own SPA, REST API, SQL database, and adapter, exchanging domain events over Azure Service Bus.

What it demonstrates:

  • Transactional outbox — entity insert and nimbus.OutboxMessages row commit on the same SqlConnection / SqlTransaction (no MSDTC), forwarded to Service Bus by an outbox dispatcher.
  • Two hosting models, identical handlers — CRM adapter runs as a .NET Worker (BackgroundService), ERP adapter runs as Azure Functions isolated worker; the same IEventHandler<T> works in both.
  • Cross-topic forwarding without loops — origin-prefixed event names (CrmAccountCreated, ErpCustomerCreated, …) plus From IS NULL filters on forwarding subscriptions make round-trip loops structurally impossible.
  • Session-based ordering[SessionKey(nameof(AccountId))] keeps the CrmAccountCreated → ErpCustomerCreated → link-erp round-trip ordered per account.
  • Operator surface — reuses nimbus-ops (the NimBus.WebApp + Resolver) for full audit trail and resubmit/skip on dead-lettered sessions.
  • Pluggable message store — runs against SQL Server by default (in a nimbus database on the same Aspire-managed SQL container as the CRM and ERP DBs); pass --StorageProvider cosmos to switch the audit/resolver/metrics store to Cosmos DB.

Run it

# 1. One-time secret (real Azure Service Bus namespace; no local emulator path)
dotnet user-secrets --project samples/CrmErpDemo/CrmErpDemo.AppHost set ConnectionStrings:servicebus "Endpoint=sb://..."

# 2. SPA dependencies (first run only)
cd samples/CrmErpDemo/Crm.Web; npm install; cd ../../..
cd samples/CrmErpDemo/Erp.Web; npm install; cd ../../..

# 3. Launch the demo (SQL Server storage by default)
dotnet run --project samples/CrmErpDemo/CrmErpDemo.AppHost

Wait for provisioner to complete in the Aspire dashboard, then create an account in crm-web and watch it round-trip through crm-adapter → Service Bus → erp-adapter Function → erp-api → back to crm-api to populate the ERP customer id. Stop erp-api mid-flow to see the failure / blocked-session / resubmit path in nimbus-ops.

Full architecture diagrams, message flows, topology details, and a v2 domains backlog are in samples/CrmErpDemo/README.md.

CI/CD

Ready-to-use deployment pipelines ship with the repository — both run infra applytopology applydeploy apps and accept optional resolver-plan / management-plan-sku / location inputs:

  • GitHub Actions: deploy.yml, manually triggered, authenticates with OIDC (no stored secrets)
  • Azure DevOps: azure-pipelines-deploy.yml, manually triggered, uses a workload-identity service connection

Teams that provision infrastructure with their own tooling can drive the Bicep templates directly using the sample parameter files in deploy/bicep/parameters/.

The Deployment Guide covers the full setup for every path: the Entra app + federated credentials for GitHub OIDC, the Azure DevOps service connection, the RBAC the deploying identity needs (the Bicep creates role assignments — plain Contributor is not enough), and the raw-Bicep walkthrough.

Documentation

Guide Description
Getting Started Step-by-step tutorial: create a publisher, subscriber, and run with Aspire
Deployment Guide All deployment paths: one-command, GitHub Actions (OIDC), Azure DevOps, raw Bicep + required RBAC
Azure Infrastructure Requirements Reference for governance review: resource inventory, provider registrations, RBAC matrix for pipeline identity, apps, and operators
Building Adapters Detailed guide for adapter authors — publisher, subscriber, middleware, hosting choice
Azure Functions Hosting Production hosting with Service Bus session triggers and DeferredProcessor
Message Flows All 12 message flow patterns with mermaid diagrams
Error Handling Adapter error-handling reference (transient, retry, dead-letter, classification)
Deferred Messages Session blocking and deferral mechanics with Mermaid diagrams
Pipeline Middleware Built-in middleware, custom behaviors, and lifecycle observers
Consumer Inbox Opt-in redelivery deduplication, providers, retention, and remaining idempotency windows
Testing Guide Test layers, conformance suites, OpenTelemetry coverage, and diagrams
CLI Reference All nb commands: infra, topology, deploy, endpoint, container, catalog
SDK API Reference Interfaces: IPublisherClient, IEventHandler, RetryPolicy, IOutbox
WebApp REST API The HTTP control plane: route map, auth, calling from outside the SPA, code generation, current external-grade gaps
Extensions Extension framework guide
Architecture System design and component overview

Acknowledgments

NimBus owes a clear intellectual debt to two open-source projects in the .NET messaging space. The design of the SDK, the pipeline of behaviors, the recoverability story (retries, dead-letter, audit, operator-driven resubmit/skip), and the framing of session-based ordering as a first-class concern are all heavily influenced by prior art from these communities.

  • NServiceBus by Particular Software — the primary source of inspiration. NimBus's approach to message handlers, the pipeline-of-behaviors pattern, the transactional outbox, the centralized audit/recovery surface (in the spirit of ServiceControl + ServicePulse), and the emphasis on operator workflows over silent dead-letter all trace back to NServiceBus's ecosystem.

NimBus is an independent implementation targeted specifically at Azure Service Bus and is not a port, fork, or derivative of either project. Any awkward design choices here are NimBus's own.

License

This project and its solutions are licensed under the MIT License.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 30 8/2/2026
2.0.0 40 7/31/2026
1.2.0 80 7/27/2026
1.1.0 111 7/3/2026
1.0.4 109 7/3/2026
1.0.3 103 7/3/2026