---
title: Service registration
summary: Services, options, startup base classes, middleware, and hosted services this library contributes to a consuming application.
status: draft
owner: Framework
last_reviewed: 2026-10-02
library: SAIF.NetCore.NHibernate
reference_type: package
---

# Service registration

This library exposes one modern registration surface, `AddNhibernateServices`/`AddNhibernateServices<T>`, which registers a singleton `IUnitOfWorkFactory` and a scoped `UnitOfWorkAccessor` for any ASP.NET Core or generic-host application. It also retains 13 legacy registration methods on `IServicesNhibernateExtensions` as `[Obsolete("Due to functional changes between .net core 2.2 and .net core 3.1, this method is obsolete to avoid startup errors.", true)]` compile-time errors, kept only to force migration off the pre-.NET Core 3.1 API; none of the 13 registers any service at runtime, although their body mechanics differ (see the catalog below).

## Registration extension catalog

| Extension method | Hosting context | Parameters | Source |
| --- | --- | --- | --- |
| `AddNhibernateServices(this IServiceCollection services, IEnumerable<Assembly> assemblyMappings, bool debugOutputSql)` | web \| API \| worker \| console | `assemblyMappings`: assemblies scanned for Fluent `ClassMap<T>` and HBM mappings, fixed for the factory's lifetime. `debugOutputSql`: when `true`, attaches `SqlDebugOutputInterceptor` to stateful sessions (active only while a debugger is attached). | `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Extensions/IServicesCollectionExtensions.cs` |
| `AddNhibernateServices<T>(this IServiceCollection services, bool debugOutputSql = false)` | web \| API \| worker \| console | `T`: any type in the single mapping assembly to scan (`Assembly.GetAssembly(typeof(T))`). `debugOutputSql` defaults to `false`. | Same file |
| `AddUnitOfWorkAccessor(this IServiceCollection services)` **[Obsolete, compile-error]** | N/A | None (no parameters beyond the `this IServiceCollection services` extension receiver) | `Extensions/IServicesNhibernateExtensions.cs` — no registration side effect; `return services;` only |
| `UseOracleSession(this IServiceCollection services, IEnumerable<Assembly> mappings, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `mappings`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `UseOracleSession(this IServiceCollection services, Assembly mappings, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `mappings`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `UseOracleSession<T>(this IServiceCollection services, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `T`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — `T` is actually used to resolve a mapping assembly before delegating to the `IEnumerable<Assembly>` overload above, which then discards it; still no registration side effect | Same file — no registration side effect |
| `UsePostGreSqlSession(this IServiceCollection services, IEnumerable<Assembly> mappings, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `mappings`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `UsePostGreSqlSession(this IServiceCollection services, Assembly mappings, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `mappings`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `UsePostGreSqlSession<T>(this IServiceCollection services, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `T`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; unlike the Oracle generic overload, `T` is never actually inspected (literal `return services;` body) | Same file — no registration side effect |
| `UseSqlSession(this IServiceCollection services, IEnumerable<Assembly> mappings, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `mappings`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `UseSqlSession(this IServiceCollection services, Assembly mappings, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `mappings`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `UseSqlSession<T>(this IServiceCollection services, bool statelessSession = false, bool formatSql = false, int batchSize = 20, bool showSql = false)` **[Obsolete, compile-error]** | N/A | `T`, `statelessSession`, `formatSql`, `batchSize`, `showSql` — all accepted but ignored; unlike the Oracle generic overload, `T` is never actually inspected (literal `return services;` body) | Same file — no registration side effect |
| `AddOracleUnitOfWork(this IServiceCollection services, string unitOfWorkInstanceName, string oracleInstance, string userName)` **[Obsolete, compile-error]** | N/A | `unitOfWorkInstanceName`, `oracleInstance`, `userName` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `AddSqlUnitOfWork(this IServiceCollection services, string unitOfWorkInstanceName, string sqlServerName, string sqlServerInstance, string userName)` **[Obsolete, compile-error]** | N/A | `unitOfWorkInstanceName`, `sqlServerName`, `sqlServerInstance`, `userName` — all accepted but ignored; no registration side effect | Same file — no registration side effect |
| `AddPostGreSqlUnitOfWork(this IServiceCollection services, string unitOfWorkInstanceName, string serverName, string instance, string userName)` **[Obsolete, compile-error]** | N/A | `unitOfWorkInstanceName`, `serverName`, `instance`, `userName` — all accepted but ignored; no registration side effect | Same file — no registration side effect |

All 13 rows marked **[Obsolete, compile-error]** above are `[Obsolete("Due to functional changes between .net core 2.2 and .net core 3.1, this method is obsolete to avoid startup errors.", true)]` on `IServicesNhibernateExtensions` — calling any of them is a **compile-time error** (the `true` argument), and every one of the 13 has zero registration side effect and no service lifetime to report, even though `UseOracleSession<T>` performs a discarded `Assembly.GetAssembly(typeof(T))` call internally before its final no-op delegation (see [BR-NH-16](business-rules.md#br-nh-16-legacy-registration-api-is-a-compile-time-error)). The checked-in `README.md` still documents this obsolete API and should not be treated as current.*

## Service registration catalog

| Service type | Implementation | Lifetime | Registered by | Condition | Source |
| --- | --- | --- | --- | --- | --- |
| `IUnitOfWorkFactory` | factory lambda: `new UnitOfWorkFactory(assemblyMappings, debugOutputSql)` | Singleton | `AddNhibernateServices` (internal `AddUnitOfWorkFactory`) | Always | `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Extensions/IServicesCollectionExtensions.cs` |
| `UnitOfWorkAccessor` | `UnitOfWorkAccessor` (concrete class, resolves `IUnitOfWorkFactory` + `IOptionsSnapshot<UnitOfWorkOptions>` from DI) | Scoped | `AddNhibernateServices` | Always | Same file |

## Options configuration

| Options type | Named instance | Configured by | Configuration keys / services read | Source |
| --- | --- | --- | --- | --- |
| `UnitOfWorkOptions` | One per `ConfigureUnitOfWorkOptions` subclass's `UniqueName`, registered by the consuming application via `services.ConfigureOptions<TSubclass>()` | Consumer-authored `ConfigureUnitOfWorkOptions` subclass (`IConfigureNamedOptions<UnitOfWorkOptions>`) | None owned by this library — see [Configuration](configuration.md) for the full `UnitOfWorkOptions` settings catalog (UO1–UO7) | `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Options/ConfigureUnitOfWorkOptions.cs`, `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Options/UnitOfWorkOptions.cs` |

## Required-but-not-registered services

| Service type | Consumer | Expected source |
| --- | --- | --- |
| `IEnvironmentClient` | Consumer's `ConfigureUnitOfWorkOptions` subclass constructor | Host application, typically via `SAIF.NetCore.ServiceExtensions` registering `SAIF.NetCore.EnvironmentClient` |
| `IDBConnectionClient` | Consumer's `ConfigureUnitOfWorkOptions` subclass constructor | Host application, typically via `SAIF.NetCore.ServiceExtensions` registering `SAIF.NetCore.DBConnectionClient` |
| `IOptionsSnapshot<UnitOfWorkOptions>` / options infrastructure | `UnitOfWorkAccessor` | Host application (ASP.NET Core / Generic Host registers `AddOptions` by default) |
| A `ConfigureUnitOfWorkOptions` subclass itself | `UnitOfWorkAccessor.UnitOfWork(key)` (via `IOptionsSnapshot<UnitOfWorkOptions>.Get`) | Host application — one subclass per logical database, registered with `services.ConfigureOptions<TSubclass>()` |

No startup base classes, feature flags, middleware pipeline, or hosted services/health checks exist in this library — it contributes no `IApplicationBuilder` or `IHostedService` surface.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [API reference](api/index.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources
- `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Extensions/IServicesCollectionExtensions.cs`
- `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Extensions/IServicesNhibernateExtensions.cs`
- `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWorkAccessor.cs`
- `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Options/ConfigureUnitOfWorkOptions.cs`
- `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Options/UnitOfWorkOptions.cs`
