Skip to content

Register NHibernate services

This operation wires the library's modern DI surface into a consuming application's IServiceCollection, so that UnitOfWorkAccessor can later be injected and used to obtain units of work.

Field Value
Operation ID OP-NH-01
Trigger Host calls services.AddNhibernateServices(assemblyMappings, debugOutputSql) or services.AddNhibernateServices<T>(debugOutputSql) at startup
Inputs assemblyMappings (or a marker type T), debugOutputSql
Outputs IUnitOfWorkFactory singleton, UnitOfWorkAccessor scoped service
Primary components IServicesCollectionExtensions.AddNhibernateServices, AddUnitOfWorkFactory
Entry point src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Extensions/IServicesCollectionExtensions.cs

Steps

  1. AddNhibernateServices<T>(bool debugOutputSql = false) resolves a single mapping assembly via Assembly.GetAssembly(typeof(T)) and forwards to the IEnumerable<Assembly> overload. Call this overload directly instead when more than one mapping assembly must be scanned.
  2. The internal AddUnitOfWorkFactory(assemblyMappings, debugOutputSql) registers AddSingleton<IUnitOfWorkFactory>(provider => new UnitOfWorkFactory(assemblyMappings, debugOutputSql)). The mapping assemblies and debugOutputSql flag are captured in this closure for the lifetime of the singleton (BR-NH-01).
  3. AddNhibernateServices then registers AddScoped<UnitOfWorkAccessor>().
  4. It returns services to support fluent chaining.
  5. It does not call AddOptions(), register any IConfigureOptions<UnitOfWorkOptions>, or register IUnitOfWork directly — the consumer must register its own ConfigureUnitOfWorkOptions subclass (see Configure named unit-of-work options).
  6. Calling AddNhibernateServices twice adds duplicate registrations; the last registration wins at resolution.*

Process flow

The diagram below visualizes the generic-overload assembly-resolution branch and the two DI registrations that follow it.

flowchart TD
    Start([Host calls AddNhibernateServices]) --> Resolve{"Generic overload?"}
    Resolve -->|Yes| GetAssembly["Assembly.GetAssembly(typeof(T))"]
    Resolve -->|No| UseGiven["Use supplied assemblyMappings"]
    GetAssembly --> RegisterFactory["AddSingleton IUnitOfWorkFactory"]
    UseGiven --> RegisterFactory
    RegisterFactory --> RegisterAccessor["AddScoped UnitOfWorkAccessor"]
    RegisterAccessor --> Return([Return services])

Failure and edge-case behavior

  • Calling AddNhibernateServices more than once registers the singleton factory multiple times; the container resolves the last registration.*
  • No exception is thrown at registration time even if assemblyMappings is empty or contains no mapped types — failures surface later, at session-factory build time.

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Extensions/IServicesCollectionExtensions.cs