Skip to content
CAI
Software that uses CAICheck a score

osstotalsoft/nbb

41.3

Weak · 21 September 2026

15.9k

lines of production code

C#

with F#

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a .NET framework (NBB) that provides a comprehensive infrastructure for building event-driven, microservices-based applications. It offers core abstractions for domain modeling, event sourcing, and messaging, with explicit support for both C\# and F\# development styles. The framework facilitates multi-tenancy, process orchestration, and functional side-effect handling, enabling developers to construct complex, scalable architectures with built-in support for distributed tracing and logging.

How it got here

2019 — Microservices and Event Sourcing

67 changes.

This period focused on establishing the foundational architecture for the NBB framework, introducing core abstractions for domain modeling, event sourcing, and messaging. It also added comprehensive sample applications for microservices and monoliths, alongside extensive unit and integration tests to validate the new components.

2020–2021 — Multi-tenancy and F\# functional support

43 changes.

This period focused on expanding the framework's multi-tenancy capabilities, introducing a comprehensive tenant identification and context management system across HTTP, messaging, and hosting layers. Simultaneously, significant functional programming support was added, including F\# libraries for effects, events, and the mediator pattern, alongside new samples and projections.

2022–2023 — Multi-tenancy and observability infrastructure

10 changes.

This period focused on implementing multi-tenancy configuration support and enhancing observability through OpenTelemetry integration. The team added features for tenant-specific settings, Serilog enrichers, and distributed tracing for messaging systems, while also introducing a DotEnv configuration provider and JetStream transport support.

Features

Add ADO.NET EventStore implementation with multi-tenancy support

Introduces the NBB.EventStore.AdoNet package, providing ADO.NET-based implementations for the EventRepository and SnapshotRepository abstractions. The core package includes AdoNetEventRepository and AdoNetSnapshotRepository, along with an options builder for configuring the connection string. Additionally, the NBB.EventStore.AdoNet.Multitenancy package adds tenant-aware repository implementations (AdoNetMultiTenantEventRepository and AdoNetMultitenantSnapshotRepository) that automatically filter queries by tenant ID, enabling multi-tenant event sourcing scenarios.

src/EventStore/NBB.EventStore.AdoNet · high confidence

Add ASP.NET Core middleware and Serilog enricher for request correlation

Introduced the NBB.Correlation.AspNet package, which provides an ASP.NET Core middleware (UseCorrelation) that extracts a correlation ID from the 'x-correlation-id' HTTP header or the 'correlationId' query string parameter, falling back to generating a new ID if neither is present. Additionally, the NBB.Correlation.Serilog package was added, supplying a log event enricher that attaches the current correlation ID to Serilog log events. These components enable end-to-end request tracing across the application and its logs.

src/Correlation/NBB.Correlation.AspNet · high confidence

Add Contracts sample with C\# and F\# implementations

The Contracts sample is introduced, providing a complete microservice example for managing contracts. The C\# implementation includes a REST API (Controllers, Startup, Program) that exposes endpoints to create, retrieve, and validate contracts, alongside command handlers that process domain events to update a read model. The F\# implementation offers an alternative functional approach using effects and message bus integration. The sample also includes database migration tools and Docker configurations for both the API and a background worker, supporting NATS and Rusi transports with OpenTelemetry tracing and metrics.

samples/MicroServices/NBB.Contracts · high confidence

Add DotEnv configuration provider support

The application can now load configuration from .env-style files containing key-value pairs. This new capability allows developers to register environment variable files via the \AddDotEnvFile\ extension method, supporting optional loading, file change reloading, and hierarchical keys using the \\\\ separator.

src/Core/NBB.Core.Configuration · high confidence

Add Entity Framework Core repository and unit-of-work implementations

The NBB.Data.EntityFramework package now provides concrete implementations for data access: EfCrudRepository for full CRUD operations, EfReadOnlyRepository for read-only access, EfQuery for direct IQueryable access, and EfUow for unit-of-work management. These are registered via extension methods in DependencyInjectionExtensions, allowing developers to inject generic repositories and queries into their applications.

src/Data/NBB.Data.EntityFramework · high confidence

Add EventStore side effects for appending, reading, and deleting streams

The NBB.EventStore.Effects package now provides side effects for interacting with an event store, including appending events to a stream, retrieving events from a stream, and deleting a stream. These effects are registered via the new AddEventStoreEffects() extension method, which wires up the corresponding handlers for the NBB effects infrastructure.

src/EventStore/NBB.EventStore.Effects · high confidence

Add F\# microservices sample for invoice management

Introduces a new F\# sample demonstrating a microservices architecture with a web API and a background worker. The API exposes endpoints to create and pay invoices, while the worker processes commands and publishes messages via NATS. The sample leverages functional domain modeling, the NBB mediator, and Giraffe for the web layer.

samples/MicroServices/NBB.Invoices.FSharp · high confidence

Add HTTP GET effect support

A new NBB.Http.Effects module is introduced, providing an effect-based abstraction for HTTP GET requests. This includes an HttpGet class that defines a SideEffect and a corresponding Handler to execute the request, alongside a static Http helper method to create the effect. Additionally, a DI extension registers the necessary services, including the HttpClient and the side-effect handler, making it easy to integrate HTTP GET operations into the application's effect system.

src/Http · high confidence

Add NATS transport implementation

Users can now configure and use NATS as a messaging transport. This adds a new \AddNatsTransport\ extension method for dependency injection, along with \NatsOptions\ for configuration and \StanMessagingTransport\ to handle subscriptions and publishing via the NATS Streaming client.

src/Messaging/NBB.Messaging.Nats · high confidence

Add NBB microservices orchestration sample

A new sample application for microservices orchestration has been added, demonstrating how to build a process manager that coordinates invoice, payment, and payable events. The sample includes a process manager implementation that tracks invoicing status through a state machine, registers message bus and event store services, and configures logging and messaging transports.

samples/MicroServices/NBB.MicroServicesOrchestration · high confidence

Add NBB monolith sample application

Introduces the NBB.Mono sample application, providing a complete monolithic architecture example. The implementation includes the entry point (Program.cs) with Serilog configuration for SQL Server logging, a Startup class that registers MediatR, the in-process message bus, EventStore, and the messaging host with correlation and resiliency middleware, along with the necessary configuration files (appsettings.json, launchSettings.json) and a Dockerfile for containerization.

samples/Monolith/NBB.Mono · high confidence

Add Payments microservice sample

The NBB.Payments sample microservice is introduced, providing a complete reference implementation for handling payables. This includes the API layer with controllers for querying and paying payables, a background worker for processing commands and domain events, and the underlying domain models (Payable, Payment) with their associated database migrations and Entity Framework Core context. The service is configured to use NATS for messaging and SQL Server for persistence, demonstrating the framework's support for event-driven architectures.

samples/MicroServices/NBB.Payments · high confidence

Add ProcessManager sample application

A new sample application named ProcessManagerSample has been added to the Orchestration area. This includes the main entry point (Program.cs, Startup.cs), configuration (appsettings.json), and domain models (Commands, Events, Queries). The sample demonstrates the use of the ProcessManager framework with two distinct process definitions: OrderProcessManager, which handles order lifecycle events (created, payment, shipping), and PollingLoopPM, which implements a timed polling loop pattern. The sample also includes a mapping profile for event transformation and a logging middleware for message subscribers.

samples/Orchestration · high confidence

Add Serilog SQL Server sink with correlation ID support

Users can now persist log events to a SQL Server table with an additional column for the correlation ID, enabling easier filtering and tracing of related log entries. The new \MsSqlServerWithCorrelation\ and \MsSqlServerWithAdditionalColumns\ extension methods on \LoggerConfiguration\ allow configuring the SQL Server sink with a dedicated correlation ID column (defaulting to 'CorrelationId' of type UniqueIdentifier) or arbitrary additional columns, simplifying the setup of structured logging to SQL Server.

src/Correlation/NBB.Correlation.Serilog.SqlServer · high confidence

Add caching and configuration-based tenant repositories

Introduced a new caching layer for tenant lookups via the \CachedTenantRepositoryDecorator\, which stores tenant data in a distributed cache for 3 minutes to reduce database load. Added a \ConfigurationTenantRepository\ that loads tenant definitions from application configuration, supporting both multi-tenant and mono-tenant modes. The \ITenantRepository\ interface was updated to include a \Get\ method that throws a \TenantNotFoundException\ if a tenant is not found, and dependency injection extensions were added to register these repositories with optional caching enabled by default.

src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories · high confidence

Add database migration tooling for the Invoices microservice

The Invoices microservice now includes a dedicated migration project that provides the infrastructure to manage the SQL Server database schema. This includes an \InvoicesDatabaseMigrator\ class that handles applying EF Core migrations and deleting the database, a \Program\ entry point that orchestrates the migration and event store setup, and the initial EF Core migration files that define the \Invoices\ table structure. A Dockerfile is also added to containerize the migration service.

samples/MicroServices/NBB.Invoices/NBB.Invoices.Migrations · high confidence

Add default HTTP tenant identification via dependency injection

A new extension method, AddDefaultHttpTenantIdentification, has been added to the NBB.MultiTenancy.Identification.Http library. This method registers the tenant identification service and configures three default token resolvers for identifying tenants: a JWT bearer token resolver (claim 'tid'), an HTTP header resolver (header 'TenantId'), and a query string resolver (parameter 'tenantId'). This simplifies the setup of multi-tenancy identification in HTTP contexts.

src/MultiTenancy/NBB.MultiTenancy.Identification.Http/Extensions · high confidence

Add default messaging tenant identification service

A new DI extension method, AddDefaultMessagingTenantIdentification, is introduced to configure multi-tenancy for messaging scenarios. It registers the tenant identification service and sets up the IdTenantIdentifier strategy, which resolves the tenant ID from the 'TenantId' header in messages.

src/MultiTenancy/NBB.MultiTenancy.Identification.Messaging/Extensions · medium confidence

Add in-memory event and snapshot repositories for testing

The NBB.EventStore.InMemory package now provides in-process implementations for the Event Repository and Snapshot Repository abstractions. These can be registered via the DI container using the new \UseInMemoryEventRepository\ extension method, allowing developers to use them as test doubles in integration tests.

src/EventStore/NBB.EventStore.InMemory · high confidence

Add in-process messaging transport registration

Users can now register the in-process messaging transport via the new \AddInProcessTransport\ extension method. This registers \IStorage\, \InProcessMessagingTransport\, \ITransportMonitor\, and \IMessagingTransport\ as singletons in the service collection, enabling in-process message handling without external infrastructure.

src/Messaging/NBB.Messaging.InProcessMessaging/Extensions · high confidence

Add messaging-based tenant identification

Introduced a new package, NBB.MultiTenancy.Identification.Messaging, which enables multi-tenancy identification via messaging headers. The package includes a \TenantIdHeaderMessagingTokenResolver\ that extracts the tenant token from a specified message header key, allowing the default identification strategy to resolve tenants from messaging envelopes.

src/MultiTenancy/NBB.MultiTenancy.Identification.Messaging · medium confidence

Add microservices sample with Kubernetes deployment and Postman collection

A new microservices sample has been added to the repository, providing a complete reference implementation for deploying NBB-based services on Kubernetes. The change includes a Postman collection for API testing, a PowerShell script to push Docker images to a container registry, and a Kubernetes manifest defining the deployment, service, and ingress resources for contracts, invoices, and payments. This enables users to quickly deploy and test the microservices architecture.

samples/MicroServices · high confidence

Add monolith database and event-store migration entry point

A new console application, NBB.Mono.Migrations, has been added to the samples/Monolith directory. It serves as the central entry point for applying database migrations across the monolith, specifically handling schema updates for Contracts, Invoices, and Payments, as well as recreating objects for the AdoNet Event Store. Configuration for connection strings and Event Store settings is provided via appsettings.json.

samples/Monolith/NBB.Mono.Migrations · high confidence

Add multi-tenancy configuration and service registration

A new \AddMultitenancy\ extension method is added to \ServiceCollectionExtensions.cs\, allowing applications to configure multi-tenancy by binding the 'MultiTenancy' configuration section to \TenancyHostingOptions\. This registers a singleton \ITenantContextAccessor\ and supports a \TenancyType\ enum (MultiTenant or MonoTenant) to define the process's tenancy model.

src/MultiTenancy/NBB.MultiTenancy.Abstractions/Hosting · high confidence

Add multi-tenancy support for Entity Framework Core

Introduces a new NBB.Data.EntityFramework.MultiTenancy package that enables multi-tenant data access in Entity Framework Core. The package provides a base \MultiTenantDbContext\ class that automatically sets the tenant ID on all modified multi-tenant entities before saving changes. It also includes extension methods to configure entities as multi-tenant, which automatically adds a shadow \TenantId\ property and a global query filter to scope queries to the current tenant's data. The implementation relies on an \ITenantContextAccessor\ to retrieve the current tenant's ID from the service provider.

src/Data/NBB.Data.EntityFramework.MultiTenancy · high confidence

Add multi-tenant messaging support with tenant context propagation

The NBB.Messaging.MultiTenancy package now provides multi-tenancy functionality for the messaging infrastructure. This includes a new \TenantMiddleware\ that identifies the tenant from incoming messages, loads tenant information, and builds the tenant context. Additionally, a \MultiTenancyMessageBusPublisherDecorator\ is introduced to automatically inject the tenant ID header into outgoing messages, ensuring that all published messages are associated with the correct tenant. The \DependencyInjectionExtensions\ class provides the \AddMultiTenantMessaging\ method to register these services.

src/Messaging/NBB.Messaging.MultiTenancy · high confidence

Add multi-tenant todo list sample application

Introduces a new multi-tenant sample application for managing todo tasks, split into an API and a background worker. The API exposes endpoints to query and create tasks, while the worker processes creation commands via a message bus. The sample includes database migrations, OpenTelemetry integration for tracing and metrics, and a Postman collection for testing. Configuration supports switching between multi-tenant and mono-tenant modes.

samples/MultiTenancy · high confidence

Add tenant token resolution interface and default implementation

Introduced the ITenantTokenResolver interface and a DefaultTenantTokenResolver implementation that returns a default tenant ID as a string token. This provides a new capability for multi-tenancy identification by allowing the system to resolve a tenant token, with a fallback to a configured default tenant ID if no specific token is present.

src/MultiTenancy/NBB.MultiTenancy.Identification/Resolvers · high confidence

Added ExpressionBuilder to construct primary key filter expressions

Added the IExpressionBuilder interface and its ExpressionBuilder implementation in the NBB.Data.EntityFramework.Internal namespace. The new code provides a mechanism to generate LINQ expressions for filtering entities by their primary key properties, supporting both single and composite keys. This enables the data layer to dynamically build query filters based on entity keys.

src/Data/NBB.Data.EntityFramework/Internal · high confidence

Added F\# monadic effect types for Reader, State, and Reader-State patterns

New F\# source files have been added to the core library, introducing monadic effect types for handling read-only context (Reader), mutable state (State), and combined reader-state scenarios. These additions provide standard functional programming abstractions, including builder types, applicative operators, and utility functions for traversing lists and results within these effect contexts.

src/Core/NBB.Core.Effects.FSharp/Data · high confidence

Added F\# support for the NBB effect system

Introduced a new F\# library (NBB.Core.Effects.FSharp) that provides F\#-style computation expressions (Lazy and Strict), operators (\<!\>, \<\*\>, \>\>=, \>=\>), and helper modules for working with the NBB effect system. This includes an F\# interpreter wrapper for dependency injection and support for list and result traversals, enabling users to compose and interpret effects in a functional, idiomatic F\# manner.

src/Core/NBB.Core.Effects.FSharp · high confidence

Added JetStream messaging transport via NATS

Users can now use JetStream for message transport by registering the new \AddJetStreamTransport\ service in their dependency injection container. This change introduces a new \NBB.Messaging.JetStream\ module that provides \IMessagingTransport\ and \ITransportMonitor\ implementations backed by the \nats.net\ client library, allowing applications to publish and subscribe to JetStream streams with configurable acknowledgement timeouts and durable consumer settings.

src/Messaging/NBB.Messaging.JetStream · high confidence

Added NATS connection management with automatic recovery

A new StanConnectionProvider class has been introduced to manage NATS streaming connections. This component handles connection lifecycle, including establishing connections, detecting lost connections, and automatically resetting the connection state when errors occur. It also implements the ITransportMonitor interface to notify about transport errors, ensuring more resilient messaging behavior.

src/Messaging/NBB.Messaging.Nats/Internal · medium confidence

Added No-op messaging transport for development and testing

A new no-op implementation of the messaging transport has been added to the NBB.Messaging.Noop package. This includes a NoopMessagingTransport that ignores publish and subscribe calls, a NoopTransportMonitor that provides empty event handlers, and a NoopDisposable for resource management. The DI extension method AddNoopTransport is now available to register these no-op services, allowing applications to run without a real message broker during development or testing.

src/Messaging/NBB.Messaging.Noop · high confidence

Added Rusi messaging transport implementation

The NBB.Messaging.Rusi package now provides a complete messaging transport implementation for the 'Rusi' system. This includes the gRPC-based \RusiMessagingTransport\ class that handles publishing and subscribing to topics, along with the associated \DependencyInjectionExtensions\ to register the transport and configure the gRPC client with retry policies. The change also introduces the \RusiOptions\ configuration class and the \rusi.proto\ file defining the service contract, enabling applications to integrate with the Rusi pub/sub infrastructure.

src/Messaging/NBB.Messaging.Rusi · high confidence

Added SQL scripts for multitenant event store operations

The multitenant AdoNet event store implementation now includes SQL scripts for core operations: creating database objects (tables, indexes, and a table type for events), appending events to streams (with optimistic concurrency checks), retrieving events and snapshots, setting snapshots, and deleting streams. These scripts support the underlying data access layer for multi-tenant event sourcing.

src/EventStore/NBB.EventStore.AdoNet.Multitenancy/Internal · high confidence

Added constrained generic decorator registration support

The NBB.Core.DependencyInjection package now provides extension methods (such as DecorateOpenGenericWhen) that allow developers to register constrained generic decorators for open generic interfaces, building on the underlying Scrutor library. This enables more flexible service decoration patterns in the dependency injection container.

src/Core/NBB.Core.DependencyInjection · high confidence

Added invoice domain event handlers for message bus integration

A new InvoiceDomainEventHandlers class was added to the application layer, implementing handlers for InvoiceCreated and InvoicePayed domain events. These handlers publish corresponding messages (PublishedLanguage.InvoiceCreated and PublishedLanguage.InvoiceMarkedAsPayed) to the message bus, enabling external systems to react to invoice lifecycle changes.

samples/MicroServices/NBB.Invoices/NBB.Invoices.Application/DomainEventHandlers · high confidence

Added legacy data contracts and MediatR integration for NBB4 compatibility

Introduced legacy base classes for commands and events (Command, CommandMetadata, Event, EventMetadata) to ensure compatibility with assemblies compiled against NBB4. Additionally, added a MediatorUowDecorator that automatically publishes domain events via MediatR after saving changes, providing a seamless integration between the unit of work and the mediator pattern.

src/Application/NBB.Application.DataContracts · high confidence

Added message publishing effect and handler

The NBB.Messaging.Effects module now includes a new PublishMessage effect, which wraps a message and optional publisher options into an ISideEffect. A corresponding handler is registered via the new DependencyInjectionExtensions.AddMessagingEffects method, which binds the PublishMessage.SideEffect to the IMessageBusPublisher for asynchronous message dispatch.

src/Messaging/NBB.Messaging.Effects · high confidence

Added tenant identification mechanisms for host and ID-based tenant lookup

Introduced new components for identifying tenants within the multi-tenancy system. The \ITenantIdentifier\ interface defines a contract for retrieving a tenant ID from a token. Two implementations are provided: \HostTenantIdentifier\, which resolves a tenant by looking up a host name via the \ITenantRepository\, and \IdTenantIdentifier\, which directly parses a GUID from the provided token. These changes enable the application to identify tenants based on either host headers or explicit ID tokens.

src/MultiTenancy/NBB.MultiTenancy.Identification/Identifiers · high confidence

Adds ASP.NET Core middleware for multi-tenancy

The package now includes a new ASP.NET Core middleware that identifies the tenant from incoming requests, loads tenant information from a repository, and builds a tenancy context. Developers can register the middleware using the new \UseTenantMiddleware()\ extension method in their application's startup configuration.

src/MultiTenancy/NBB.MultiTenancy.AspNet · high confidence

Adds OpenTelemetry tracing for message bus publish and subscribe operations

The NBB.Messaging.OpenTelemetry package now provides automatic distributed tracing for messaging. Publishers create spans with kind 'producer' and subscribers create spans with kind 'consumer', both tagged with destination, component, and correlation ID. The library registers decorators for both publisher and subscriber interfaces and provides a TracerProviderBuilder extension to enable instrumentation.

src/Messaging/NBB.Messaging.OpenTelemetry · high confidence

Adds core abstractions and F\# functional data types

The NBB.Core.Abstractions package now includes a set of cross-cutting interfaces and extensions, including ICorrelatable, IEventedEntity, IIdentifiedEntity, IKeyProvider, IMementoProvider, and IUow for unit of work patterns, alongside concurrency exceptions and paging models. Additionally, the NBB.Core.FSharp package introduces functional data types: Reader, State, and ReaderState monadic computations with associated builder and extension modules.

src/Core/NBB.Core.Abstractions · high confidence

Initial SQL scripts for EventStore database schema and operations

The EventStore AdoNet provider now includes a complete set of SQL scripts to manage the underlying database schema and data operations. This includes scripts to create and drop database objects (tables for events and snapshots, plus a table-valued parameter type), as well as specific scripts for appending events to streams (with and without version checking), retrieving events and snapshots from streams, deleting streams, and setting snapshots. These scripts enable the creation, querying, and maintenance of the event store's persistent state.

src/EventStore/NBB.EventStore.AdoNet/Internal/SqlScripts · high confidence

Initial release of the NBB.Invoices.Worker microservice

The NBB.Invoices.Worker microservice is introduced, providing a .NET-based background worker that processes invoice-related commands and events. It is configured with MediatR for command handling, a messaging host supporting both NATS and Kafka transports, and an EventStore for persistence. The service includes logging to SQL Server and console, correlation ID enrichment, and default resiliency and exception-handling middleware in its message pipeline.

samples/MicroServices/NBB.Invoices/NBB.Invoices.Api, samples/MicroServices/NBB.Invoices/NBB.Invoices.Worker · high confidence

Introduce AdoNet EventStore database migration tooling

Added a new \NBB.EventStore.AdoNet.Migrations\ project that provides a command-line utility and library for creating or recreating the database objects required by the AdoNet EventStore. The \AdoNetEventStoreDatabaseMigrator\ class exposes \CreateDatabaseObjectsAsync\ and \DropDatabaseObjectsAsync\ methods, supporting both single-tenant and multi-tenant database schemas based on configuration. This allows users to initialize or reset their event store database structure directly from the command line or via code.

src/EventStore/NBB.EventStore.AdoNet.Migrations · high confidence

Introduce Event Sourcing Data Access Layer

Added the NBB.Data.EventSourcing package, which provides an EventSourcedRepository for managing event-sourced domain models. This includes dependency injection extensions to register the repository and configure options like snapshot frequency, as well as the core repository implementation that handles loading aggregates from the event store and snapshot store, and saving uncommitted events with automatic snapshotting and MediatR event publishing.

src/Data/NBB.Data.EventSourcing · high confidence

Introduce Event Store and Snapshot Store abstractions

Added core abstractions for event sourcing and snapshotting. The new \IEventStore\ interface defines methods to append and retrieve events from streams, while \ISnapshotStore\ defines how to store and load snapshots. A \SnapshotEnvelope\ data contract and a \NullSnapshotStore\ implementation are also included. Additionally, an \EventStoreUowDecorator\ is provided to automatically persist events to the store after saving changes, and utility extensions for entity stream identification are added.

src/EventStore/NBB.EventStore.Abstractions · high confidence

Introduce F\#-specific mediator and pipeline abstractions

Added a new F\#-oriented application mediator implementation, providing typed pipelines for commands, queries, and events. The change introduces core types (ICommand, IQuery, IEvent) and handler/middleware abstractions (RequestHandler, RequestMiddleware, etc.) along with combinators for composing pipelines. A Mediator record and DI extension (AddMediator) are provided to wire the pipelines into the service collection, enabling F\# projects to use a functional, effect-based mediator pattern.

src/Application/NBB.Application.Mediator.FSharp · high confidence

Introduce MediatR side-effect integration

Added new files in the NBB.Application.MediatR.Effects module to integrate MediatR with the side-effect pattern. This includes a DI extension method to register the necessary handlers, and static helper methods to create Effect wrappers for MediatR's Send and Publish operations, enabling a more functional approach to handling MediatR requests and notifications.

src/Application/NBB.Application.MediatR.Effects · high confidence

Introduce NBB.Core.Effects for functional, composable side-effect handling

The NBB.Core.Effects library is introduced, providing a functional, type-safe, and composable asynchronous and concurrent programming model for .NET. This new feature allows developers to represent side-effects at the type level without executing them immediately, enabling pure function composition. The library includes an \IInterpreter\ to execute effects, a \SideEffectBroker\ to resolve handlers, and specific effect types for parallel execution, sequencing, try/catch, and thunk-based impure operations. Registration is handled via \DependencyInjectionExtensions.AddEffects()\ and \AddSideEffectHandler()\.

src/Core/NBB.Core.Effects · high confidence

Introduce NBB.EventStore package with DI registration and serialization

The NBB.EventStore package now provides a concrete EventStore and SnapshotStore implementation, along with a DI extension (AddEventStore) that registers the IEventStore and ISnapshotStore services. The EventStore supports appending and retrieving events from streams, while the SnapshotStore handles loading and storing snapshots. Both use a configurable JSON serializer (defaulting to Newtonsoft.Json) for event and snapshot data, and include logging for performance tracking.

src/EventStore/NBB.EventStore · high confidence

Introduce NBB.Messaging.Abstractions with a new message bus, serialization, and dead-letter queue

The NBB.Messaging.Abstractions package now provides a complete messaging abstraction, including a message bus for publishing and subscribing to messages, a default dead-letter queue for handling failed messages, and a JSON-based serialization/deserialization implementation. The bus supports dynamic deserialization, topic resolution with environment-based prefixes, and automatic registration via DI extensions.

src/Messaging/NBB.Messaging.Abstractions · high confidence

Introduce NBB.Messaging.Host with background service, health checks, and context propagation

Adds the NBB.Messaging.Host package, providing a background service (MessagingHostService) that manages the lifecycle of the messaging host. The update introduces a new IMessagingHost interface, configuration options (MessagingHostOptions) for retry and delay settings, and a health check (MessagingHostHealthCheck) to monitor host status. It also adds a decorator (MessagingContextBusPublisherDecorator) that automatically propagates correlation IDs and messaging context headers to outgoing messages, and registers all components via ServiceCollectionExtensions.

src/Messaging/NBB.Messaging.Host · high confidence

Introduce NBB.ProjectR for functional-style read-model projections

Added the NBB.ProjectR library to support functional-style read-model projections inspired by Elm. This includes the core projection logic, dependency injection extensions for service registration, and interfaces for managing projection state and metadata. The implementation leverages MediatR for event handling and integrates with the existing event store and snapshot store infrastructure.

src/Projections · high confidence

Introduce Process Manager runtime and definition APIs

The Process Manager feature is now available, providing a complete runtime for managing long-running business processes. This includes the \NBB.ProcessManager.Definition\ namespace with \IDefinition\<TData\>\ and related delegates for defining process behavior, and the \NBB.ProcessManager.Runtime\ namespace for execution, including the \ProcessExecutionCoordinator\, \Instance\ state management, and timeout handling via \TimeoutsManager\. The system supports event-driven process orchestration with automatic state persistence and timeout-based event publishing.

src/Orchestration/NBB.ProcessManager.Runtime · high confidence

Introduce core domain primitives and serialization support

The NBB.Domain package now provides foundational building blocks for domain modeling, including abstract base classes for entities, aggregate roots (Evented, Emit/Apply, and EventSourced), and value objects (SingleValueObject, Identity, Enumeration). To support persistence and transport, a custom JSON converter (SingleValueObjectConverter) is added to serialize/deserialize SingleValueObject types as their underlying primitive values.

src/Domain/NBB.Domain · high confidence

Introduce correlation ID management for request tracing

The NBB.Correlation package now provides a CorrelationManager to generate and track unique correlation IDs across application boundaries. Users can create a new correlation scope using CorrelationManager.NewCorrelationId(), which automatically clears the ID when the scope is disposed, or retrieve the current correlation ID via CorrelationManager.GetCorrelationId().

src/Correlation/NBB.Correlation · high confidence

Introduce data access and domain contracts for the Invoices microservice

Added the data access layer for the Invoices microservice, including the InvoicesDbContext for Entity Framework Core, dependency injection extensions for configuring read/write data access, and domain contracts (commands and integration events) that define the service's public API.

samples/MicroServices/NBB.Invoices/NBB.Invoices.Data · high confidence

Introduce generic pipeline builder with middleware support

Added a new generic pipeline builder in the NBB.Core.Pipeline library that enables configuring and executing a chain of middleware. The update introduces the IPipelineBuilder interface and PipelineBuilder class, allowing developers to register middleware either as functional delegates or as classes implementing the new IPipelineMiddleware interface. This provides a fluent API for constructing request processing pipelines with support for dependency injection via the service provider.

src/Core/NBB.Core.Pipeline · high confidence

Introduce in-process messaging transport with internal storage implementation

Added internal components for in-process messaging: the IStorage interface and its Storage implementation using ConcurrentQueue and AutoResetEvent for message handling, along with the InProcessMessagingTransport class that implements IMessagingTransport and ITransportMonitor to manage subscriptions and publishing within the same process.

src/Messaging/NBB.Messaging.InProcessMessaging/Internal · high confidence

Introduce multi-tenancy abstractions and logging scope

The package now provides core multi-tenancy abstractions, including a \Tenant\ record that stores tenant identity (id, code) and an \Enabled\ status, alongside a \TenantContext\-based \TenantLogScope\ that automatically injects \TenantId\ and \TenantCode\ into structured logging. The diff also adds a \TenantNotFoundException\ for missing tenant scenarios and a \README.md\ documenting the new \ITenantConfiguration\ interface and extension methods for tenant-specific configuration.

src/MultiTenancy/NBB.MultiTenancy.Abstractions · high confidence

Introduce multi-tenancy tenant identification service and strategy

The NBB.MultiTenancy.Identification package now provides a new abstraction for identifying tenants. It introduces a \TenantIdentificationService\ that applies a configurable list of \TenantIdentificationStrategy\ components. Each strategy iterates through a chain of \TenantTokenResolver\ implementations (such as JWT header, HTTP header, or query string resolvers) to obtain a tenant token, which is then passed to a \TenantIdentifier\ to resolve the final tenant ID. This allows users to register multiple identification methods in a specific order of precedence.

src/MultiTenancy/NBB.MultiTenancy.Identification · high confidence

Introduce multi-tenant identification service and builder

Added a new multi-tenant identification service (\ITenantIdentificationService\ and \DefaultTenantIdentificationService\) that iterates through registered \TenantIdentificationStrategy\ instances to resolve the current tenant ID. The \TenantServiceBuilder\ provides a fluent API for registering tenant identification strategies and their associated token resolvers via dependency injection, allowing applications to configure how tenants are identified from various tokens.

src/MultiTenancy/NBB.MultiTenancy.Identification/Extensions · high confidence

Introduce process manager definition builder and effect system

Added new classes in the NBB.ProcessManager.Definition.Builder namespace to support process orchestration. This includes AbstractDefinition for defining event activities and correlations, EventActivitySet to manage event handlers and state transitions, and extension methods (SendCommand, Schedule, PublishEvent) to configure side effects. The builder pattern allows users to define how the process manager reacts to events, manages state, and triggers commands or timeouts.

src/Orchestration/NBB.ProcessManager.Definition/Builder · high confidence

Introduce repository abstractions with cancellation token support

The NBB.Data.Abstractions package now provides lightweight interfaces for data access: ICrudRepository, IEventSourcedRepository, IReadOnlyRepository, and IUowRepository. All asynchronous methods across these repositories now accept a CancellationToken, allowing callers to cancel operations. The IUowRepository interface also exposes the Unit of Work for saving changes.

src/Data/NBB.Data.Abstractions · high confidence

Introduce schema resolution and JSON schema generation for data contracts

Added the NBB.Application.DataContracts.Schema package, which provides an ISchemaResolver interface and JsonSchemaResolver implementation to generate JSON schemas (v4) from CLR types. The update includes a SchemaDefinition model and a SchemaDefinitionUpdated event, enabling runtime schema generation and publishing via messaging for data contracts.

src/Application/NBB.Application.DataContracts.Schema · high confidence

Introduce tenant context access and flow management

Added new abstractions for managing multi-tenant context within the application. This includes the ITenantContextAccessor interface and its TenantContextAccessor implementation, which use AsyncLocal storage to track the current tenant. A TenantContext class and TenantContextFlow struct are introduced to support scoped tenant context switching, allowing code to temporarily change the active tenant and automatically restore the previous context upon disposal. Extension methods are also provided to simplify tenant context changes and retrieve tenant identifiers.

src/MultiTenancy/NBB.MultiTenancy.Abstractions/Context · high confidence

Introduces F\# Evented monad for evented computations

Adds the NBB.Core.Evented.FSharp library, providing an F\# writer monad for evented computations. This introduces the \Evented\<'a, 'e\>\ type, which pairs a payload with a list of events, along with monadic operators (\\<!\>\, \\<\*\>\, \\>\>=\, \\>=\>\) and a computation expression builder (\evented\) to accumulate events imperatively. It also includes utility functions for traversing and sequencing evented operations on lists and results.

src/Core/NBB.Core.Evented.FSharp · high confidence

Introduces a new fluent builder API for configuring the messaging host

The messaging host now uses a new builder pattern to configure subscribers, options, and pipelines. Users can now use \IMessagingHostBuilder\ to add subscriber services, set options via \SubscriberOptionsBuilder\ (including dynamic deserialization), and define processing pipelines. This replaces the previous configuration approach with a more structured, fluent interface for setting up message handling in the host.

src/Messaging/NBB.Messaging.Host/Builder · high confidence

Introduces domain abstraction interfaces and unit of work decorator

The NBB.Domain.Abstractions package now provides core domain-driven design abstractions, including interfaces for entities, aggregate roots (including evented and event-sourced variants), and a snapshot-capable entity interface. Additionally, a DomainUowDecorator is introduced to manage state changes before saving, ensuring that aggregate roots are marked as committed during the save operation.

src/Domain/NBB.Domain.Abstractions · high confidence

Introduces domain models for invoice management and locking

The NBB.Invoices.Domain project now includes the core domain models for the invoice aggregate, including the Invoice entity with its associated domain events (InvoiceCreated, InvoicePayed) and an IInvoiceRepository interface. Additionally, an InvoiceLock aggregate root is introduced to handle distributed locking logic, featuring state management for lock acquisition and release.

samples/MicroServices/NBB.Invoices/NBB.Invoices.Domain · high confidence

New HTTP-based tenant token resolvers for multi-tenancy identification

The NBB.MultiTenancy.Identification.Http package now includes several new classes that extract tenant tokens from various HTTP request sources. These include FormTokenResolver for form data, HeaderHttpTokenResolver for standard headers, HeaderRegexHttpTokenResolver for header values matching a regex, HostHttpTenantTokenResolver for the request host, HostRefererHttpTokenResolver for the Referer header, JwtBearerTokenResolver for JWT claims, and QueryStringHttpTokenResolver for query string parameters. The package also provides a default strategy registration via AddDefaultHttpTenantIdentification().

src/MultiTenancy/NBB.MultiTenancy.Identification.Http · high confidence

New Invoices API controller exposing invoice endpoints

Added the InvoicesController, which provides HTTP endpoints for listing invoices, retrieving a specific invoice by ID, creating new invoices, and processing an existing invoice. The controller uses dependency injection to access a message bus publisher and an invoice query source, with each async method accepting a CancellationToken for cancellation support.

samples/MicroServices/NBB.Invoices/NBB.Invoices.Api/Controllers · high confidence

New Serilog enrichers and OpenTelemetry tracing sink

Added Serilog enrichers for service and tenant identification, plus an OpenTelemetry tracing sink. The ServiceIdentifier enricher adds a service name to log context, falling back to the entry assembly name. The TenantId enricher adds tenant ID and code to logs, handling mono-tenant scenarios. The OpenTelemetryTracingSink integrates Serilog with OpenTelemetry, filtering out Microsoft framework logs by default and mapping log properties to activity events.

src/Tools · high confidence

New fluent API for selecting message types and topics

The messaging host now provides a new set of interfaces and implementations (IAssemblySelector, ITypeSelector, ITopicSelector, etc.) that allow users to configure subscriber services by selecting message types from specific assemblies, calling assemblies, or explicit type lists, and by filtering classes based on base types or predicates. This enables a more flexible and expressive way to register message handlers and topics during host building.

src/Messaging/NBB.Messaging.Host/Builder/TypeSelector · high confidence

New messaging pipeline with built-in middleware for correlation, validation, and resiliency

The messaging host now includes a configurable processing pipeline composed of several new middleware components. CorrelationMiddleware automatically creates a correlation scope from message headers. SchemaMessageValidatorMiddleware enforces the presence of Source and CorrelationId headers. ExceptionHandlingMiddleware logs errors and routes failed messages to a dead-letter queue. DefaultResiliencyMiddleware implements retry policies for out-of-order and concurrency exceptions. MediatRMiddleware forwards messages to MediatR for handling. These are wired up via extension methods in MessagingPipelineExtensions.

src/Messaging/NBB.Messaging.Host/MessagingPipeline · medium confidence

New multi-tenancy configuration infrastructure

Added a new set of classes and extensions in the NBB.MultiTenancy.Abstractions.Configuration namespace to manage tenant-specific configuration. This includes a TenantConfiguration implementation that merges default and tenant-specific settings, a MergedConfigurationSection to handle configuration precedence, and extension methods to retrieve connection strings and typed values. The TenantInfrastructure class provides a method to retrieve connection strings for all tenants.

src/MultiTenancy/NBB.MultiTenancy.Abstractions/Configuration · high confidence

New timeout side effects for process management

The process manager now supports defining and cancelling timeouts. New side-effect types, including RequestTimeout and CancelTimeouts, allow users to schedule a message to be delivered after a specified time span, or cancel pending timeouts for a process instance.

src/Orchestration/NBB.ProcessManager.Definition/SideEffects · high confidence

Repository initialization and project structure

The repository was initialized with the foundational project structure, including solution filters (.slnf) to organize the solution into logical groups (Core, Effects, EventStore, Messaging, ProcessManager, Samples), a Directory.Build.props file to centralize package versions and build properties, and a dependencies.props file to manage third-party library versions. This establishes the baseline architecture for the .Net Building Blocks (NBB) framework.

(repo-wide) · high confidence

Behavioural changes

Added backward compatibility for NBB 4 topic resolution

A new backward compatibility layer has been introduced for the messaging system, allowing applications to resolve topics using NBB 4 conventions. This includes a configurable DI extension that decorates the topic registry with an NBB 4-specific implementation, which automatically prepends prefixes like 'ch.commands.', 'ch.events.', or 'ch.messages.' based on message types. This ensures that older message types continue to resolve to the correct topics under the new naming scheme.

src/Messaging/NBB.Messaging.BackwardCompatibility · medium confidence

Added invoice command handlers for creation, payment marking, and processing with locking

New command handlers were added to the NBB.Invoices application to support creating invoices, marking them as paid, and processing them. The process handler specifically implements an event-sourced locking mechanism to ensure safe concurrent processing of invoices, preventing race conditions during the CPU-intensive process step.

samples/MicroServices/NBB.Invoices/NBB.Invoices.Application/CommandHandlers · medium confidence

Improved messaging host lifecycle and restart handling

The messaging host now includes an ExecutionMonitor to track active message handlers, enabling the host to wait for in-flight messages to complete before stopping. Additionally, the host's start/stop lifecycle has been refactored to support scheduled restarts and more robust error handling, including automatic restarts on transport errors and retry logic during startup.

src/Messaging/NBB.Messaging.Host/Internal · medium confidence

Test coverage

Added EventStore benchmark suite; Added F\# effect benchmark tests; Added integration tests for EventStore and SnapshotStore concurrency; Added integration tests for ProjectR projections; Added integration tests for Rusi transport subscription and unsubscribe behavior; Added unit tests for AdoNet event store configuration binding; Added unit tests for DotEnv configuration provider; Added unit tests for EventSourcedRepository and ExpressionBuilder; Added unit tests for EventStore and SnapshotStore components; Added unit tests for F\# Reader, State, and ReaderState monads; Added unit tests for F\# effect computation expressions; Added unit tests for HTTP effects; Added unit tests for HTTP-based tenant token resolvers; Added unit tests for HostTenantIdentifier and IdTenantIdentifier; Added unit tests for InMemoryRepository; Added unit tests for Mediator effects; Added unit tests for Rusi messaging transport; Added unit tests for Serilog enrichers; Added unit tests for TenantIdHeaderMessagingTokenResolver; Added unit tests for domain primitives and aggregates; Added unit tests for in-process messaging and storage; Added unit tests for messaging abstractions and data contracts; Added unit tests for messaging pipeline middleware; Added unit tests for messaging side effects; Added unit tests for multi-tenancy configuration and tenant management; Added unit tests for multi-tenant entity framework operations; Added unit tests for multi-tenant message publishing; Added unit tests for tenant identification DI extensions; Added unit tests for tenant identification service; Added unit tests for the F\# Application Mediator; Added unit tests for the F\# Evented workflow and list sequence operators; Added unit tests for the NBB.Core.Pipeline middleware execution; Added unit tests for the ProcessManager orchestration logic; Added unit tests for the effects subsystem; Added unit tests for the messaging host lifecycle and subscriber configuration.

Dependencies

Upgrade samples to .NET 10.0

The sample projects in the repository have been upgraded to target .NET 10.0. This includes the microservices (Contracts, Invoices, Payments, F\# Invoices), the monolith, and the orchestration sample. Most C\# projects now target net10.0, while some legacy or specific samples (like NBB.Contracts.Application.Commands) remain on older frameworks or are newly added with the new target. This ensures all samples are built against the latest .NET runtime version.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 39 → 41 (+2.2)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 51 → 51 (-0.1)
  • Architecture 77 → 78 (+0.7)
  • Maturity 55 → 55 (+0.0)
  • Readiness 54 → 57 (+3.4)
  • Security 19 → 23 (+3.9)
  • Domain Modelling 74 → 68 (-5.2)
  • Event-Driven 82 → 82 (+0.0)
  • Event Sourcing 100 (new)
  • Performance 66 → 66 (+0.0)

Resolved (33)

  • Bounded contexts not declared
  • Duplicated block (12 lines × 2) (samples/Orchestration/ProcessManagerSample/OrderProcessManager.cs)
  • Duplicated block (17 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (19 lines × 2) (src/Core/NBB.Core.Abstractions/TypeExtensions.cs)
  • Duplicated block (19 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (19 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (23 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (9 lines × 3) (samples/MicroServices/NBB.Contracts/NBB.Contracts.Migrations/Program.cs)
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High CVE: System.Security.Cryptography.Xml 9.0.0
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 13 more

New (189)

  • Ambiguous route generation. In ASP.NET Core, having two Get methods with different signatures (one with no parameters, one with Guid) can lead to ambiguous route conflicts if not explicitly configured with [HttpGet] attributes specifying different routes (e.g., [HttpGet] vs [HttpGet("{id}")]). Without explicit routing attributes shown, this is a potential runtime error or confusing API surface.
  • CRAP 108: TypeInfo.ParseInternal (src/Messaging/NBB.Messaging.Abstractions/DefaultMessageTypeRegistry.cs)
  • CRAP 30: ActivityExtensions.SetException (src/Core/NBB.Core.Abstractions/ActivityExtensions.cs)
  • CRAP 30: StatusHelper.GetTagValueForStatusCode (src/Core/NBB.Core.Abstractions/ActivityExtensions.cs)
  • CRAP 41: NewtonsoftJsonMessageSerDes.ResolveRuntimeType (src/Messaging/NBB.Messaging.Abstractions/NewtonsoftJsonMessageSerDes.cs)
  • CRAP 42: AdoNetEventRepository.AppendEventsToStreamExpectedVersionAsync (src/EventStore/NBB.EventStore.AdoNet/AdoNetEventRepository.cs)
  • CRAP 42: DefaultDeadLetterQueue.Push (src/Messaging/NBB.Messaging.Abstractions/DefaultDeadLetterQueue.cs)
  • CRAP 42: MessageBusSubscriber.SubscribeAsync (src/Messaging/NBB.Messaging.Abstractions/MessageBusSubscriber.cs)
  • CRAP 48: DefaultMessageTypeRegistry.GetTypeByNameInternal (src/Messaging/NBB.Messaging.Abstractions/DefaultMessageTypeRegistry.cs)
  • Documentation: no installation or build instructions (README.md)
  • Duplicated block (10 lines × 2) (samples/MicroServices/NBB.Invoices/NBB.Invoices.Api/Program.cs)
  • Duplicated block (10 lines × 2) (samples/MicroServices/NBB.Invoices/NBB.Invoices.Data/DependencyInjectionExtensions.cs)
  • Duplicated block (10 lines × 2) (samples/MicroServices/NBB.Payments/NBB.Payments.Data/DependencyInjectionExtensions.cs)
  • Duplicated block (11 lines × 2) (samples/MultiTenancy/NBB.Todo.Api/Program.cs)
  • Duplicated block (11 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (11 lines × 3) (samples/MicroServices/NBB.Invoices/NBB.Invoices.Api/Startup.cs)
  • Duplicated block (13 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (13 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (14 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • Duplicated block (16 lines × 2) (src/Core/NBB.Core.DependencyInjection/ReflectionExtensions.cs)
  • …and 169 more

API surface

  • Unchanged — 14 HTTP endpoints

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

osstotalsoft/nbb was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit a1a5aacd24a66c4eaf96947252f484b9cb2766c0 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.