---
title: Service registration
summary: Services, options, startup base classes, middleware, and hosted services this library contributes to a consuming application.
status: draft
owner: Messaging Platform Team
last_reviewed: 2026-10-21
library: SAIF.NCore.Messaging
reference_type: package
---

# Service registration

SAIF.NCore.Messaging exposes three `IServiceCollection` extension methods that
work in any hosting context: `AddSaifMessaging` registers the message bus
client, serializer, publisher, and handler dispatcher; `AddSaifMessagingOutbox`
adds the transactional outbox store and a background dispatcher for worker and
API hosts; and `AddMessageHandler<TMessage, THandler>` registers one message
handler. A consuming application must call `AddSaifMessaging` first, register
its own handlers, and supply an `IEnvironmentClient` and an
`IOutboxConnectionFactory` because the library resolves both but never
registers them.

## Registration extension catalog

Extension methods a consuming application calls to register this library's services.

| Extension method | Hosting context | Parameters | Source |
| --- | --- | --- | --- |
| `AddSaifMessaging(this IServiceCollection services, IConfiguration configuration)` | any | `configuration` is the application's root configuration; its `Messaging` section is bound to `MessagingOptions`. Must be called before `AddSaifMessagingOutbox` and `AddMessageHandler`. | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `AddSaifMessagingOutbox(this IServiceCollection services, IConfiguration configuration)` | API, worker | `configuration` is the application's root configuration; its `Messaging:Outbox` section is bound to `OutboxOptions`. Skips the hosted dispatcher when the `SAIF_MESSAGING_DISABLE_DISPATCH` environment variable is `true`. | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `AddMessageHandler<TMessage, THandler>(this IServiceCollection services)` | any | No parameters. `THandler` must implement `IMessageHandler<TMessage>`. Each call adds one handler; every handler registered for a message type is invoked for that type. | src/SAIF.NCore.Messaging/Extensions/MessageHandlerRegistrationExtensions.cs |

## Service registration catalog

| Service type | Implementation | Lifetime | Registered by | Condition | Source |
| --- | --- | --- | --- | --- | --- |
| `IMessageSerializer` | `JsonMessageSerializer` (from the bundled `SAIF.NCore.Messaging.Serialization` assembly) | Singleton | `AddSaifMessaging` | Always, through `TryAddSingleton`; a host registration made earlier wins | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IMessageClock` | `SystemMessageClock` | Singleton | `AddSaifMessaging` | Always, through `TryAddSingleton`; a host registration made earlier wins | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IMessageBusClient` | `ServiceBusClientAdapter` | Singleton | `AddSaifMessaging` | Always | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IMessageAuditSink` | factory: `provider => null`, so the service resolves to `null` | Singleton | `AddSaifMessaging` | Always; `MessagePublisher` skips auditing when the resolved sink is `null` | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IMessagePublisher` | `MessagePublisher` | Scoped | `AddSaifMessaging` | Always | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IMessageHandlerDispatcher` | `MessageHandlerDispatcher` | Scoped | `AddSaifMessaging` | Always | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IPostConfigureOptions<MessagingOptions>` | `ConfigureMessagingOptions` | Transient | `AddSaifMessaging` | Always, through `ConfigureOptions<ConfigureMessagingOptions>()` | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IOutboxStore` | `SqlOutboxStore` | Scoped | `AddSaifMessagingOutbox` | Always | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IHostedService` | `OutboxDispatchService` | Singleton | `AddSaifMessagingOutbox` | `SAIF_MESSAGING_DISABLE_DISPATCH` is not `true` | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |
| `IMessageHandler<TMessage>` | `THandler` | Transient | `AddMessageHandler<TMessage, THandler>` | Once per call | src/SAIF.NCore.Messaging/Extensions/MessageHandlerRegistrationExtensions.cs |

## Options configuration

| Options type | Named instance | Configured by | Configuration keys / services read | Source |
| --- | --- | --- | --- | --- |
| `MessagingOptions` | default | `Configure<MessagingOptions>(configuration.GetSection("Messaging"))` in `AddSaifMessaging` | `Messaging:ServiceName`, `Messaging:DefaultTopic`, `Messaging:MaxDeliveryAttempts`, `Messaging:PublishTimeoutSeconds` | src/SAIF.NCore.Messaging/Options/MessagingOptions.cs |
| `MessagingOptions` | default | `ConfigureMessagingOptions` (post-configure, runs after binding) | `IEnvironmentClient`: `Messaging:TopicPrefix` (read only when `HasSetting` returns true) and the secure setting `Messaging:ConnectionString` | src/SAIF.NCore.Messaging/Options/ConfigureMessagingOptions.cs |
| `OutboxOptions` | default | `Configure<OutboxOptions>(configuration.GetSection("Messaging:Outbox"))` in `AddSaifMessagingOutbox` | `Messaging:Outbox:PollIntervalSeconds`, `Messaging:Outbox:BatchSize`, `Messaging:Outbox:RetentionHours` | src/SAIF.NCore.Messaging/Options/OutboxOptions.cs |

## Feature flags

Properties a consumer overrides, and environment variables a base class reads, that change registration or middleware behavior. Environment variables are also listed in [Configuration](configuration.md).

| Name | Kind | Default | Effect | Source |
| --- | --- | --- | --- | --- |
| `SAIF_MESSAGING_DISABLE_DISPATCH` | Environment variable (process) | Unset, treated as `false` | When `true`, `AddSaifMessagingOutbox` does not register `OutboxDispatchService`. Outbox rows are still written by `MessagePublisher` but this process never dispatches them. | src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs |

## Hosted services and health checks

| Type | Kind | Registered by | Behavior | Source |
| --- | --- | --- | --- | --- |
| `OutboxDispatchService` | BackgroundService | `AddSaifMessagingOutbox` | Waits `Messaging:Outbox:PollIntervalSeconds` between cycles using a `PeriodicTimer`. Each cycle creates a service scope, reads up to `Messaging:Outbox:BatchSize` pending rows from `IOutboxStore`, sends them through `IMessageBusClient`, and marks them dispatched. A failed cycle is logged and the loop continues on the next tick. The stopping token is passed to the store and bus calls, so an in-flight batch is abandoned on shutdown and its rows stay pending. | src/SAIF.NCore.Messaging/Hosting/OutboxDispatchService.cs |

## Required-but-not-registered services

Services this library's types resolve that none of its registration methods add. The consuming application, or another library, must register them.

| Service type | Consumer | Expected source |
| --- | --- | --- |
| `IEnvironmentClient` | `ConfigureMessagingOptions` | Host application, through the environment client registration of `SAIF.NetCore.ServiceExtensions`† |
| `IOutboxConnectionFactory` | `SqlOutboxStore` | Host application; this library declares the interface and the host supplies the implementation |
| `IMessageHandler<TMessage>` | `MessageHandlerDispatcher` | Host application, through `AddMessageHandler<TMessage, THandler>` for each message type it consumes |
| `ILogger<T>` | `MessagePublisher`, `OutboxDispatchService` | Host application; added by the generic host or `AddLogging` |

## Related documentation
- Index
- Overview
- Architecture
- Dependencies
- [Configuration](configuration.md)
- Operations and processes
- Business rules
- API reference

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. They describe inherited behavior from the
> indicated origin library and should be verified if the dependency version changes.

## Sources
- src/SAIF.NCore.Messaging/Extensions/ServiceCollectionExtensions.cs
- src/SAIF.NCore.Messaging/Extensions/MessageHandlerRegistrationExtensions.cs
- src/SAIF.NCore.Messaging/Options/MessagingOptions.cs
- src/SAIF.NCore.Messaging/Options/OutboxOptions.cs
- src/SAIF.NCore.Messaging/Options/ConfigureMessagingOptions.cs
- src/SAIF.NCore.Messaging/Hosting/OutboxDispatchService.cs
- src/SAIF.NCore.Messaging/Outbox/IOutboxConnectionFactory.cs
- src/SAIF.NCore.Messaging.Serialization/JsonMessageSerializer.cs
- src/SAIF.NCore.Messaging/SAIF.NCore.Messaging.csproj
