Configuration settings¶
This library reads no configuration keys of its own — a search of every source file found no IConfiguration, GetSettingValue, GetSecureSetting, HasSetting, ConfigurationManager, or Environment.GetEnvironmentVariable usage. Instead, it exposes a consumer-facing configuration surface: the named-options POCO UnitOfWorkOptions (with non-trivial defaults), the abstract configurer ConfigureUnitOfWorkOptions that each consuming application subclasses once per logical database, and two registration parameters on AddNhibernateServices.
Configuration retrieval methods¶
| Method | Class / Interface | Namespace | Usage pattern |
|---|---|---|---|
| Named options type | UnitOfWorkOptions |
SAIF.NetCore.NHibernate.Options |
POCO with seven settable properties; its parameterless constructor applies the library defaults. One named instance describes one logical database connection. |
| Abstract named-options configurer | ConfigureUnitOfWorkOptions : IConfigureNamedOptions<UnitOfWorkOptions> |
SAIF.NetCore.NHibernate.Options |
The consumer subclasses it and registers it with services.ConfigureOptions<TSubclass>(). The subclass must implement UniqueName, Database, and GetConnectionString(). GetConnectionString() is called from the base class's constructor (this._connectionString = GetConnectionString();) — a virtual/abstract call executing before the derived class's own constructor body runs. If the override depends on fields the derived constructor itself assigns, those fields are not yet initialized when GetConnectionString() runs, so it can read nulls/defaults instead of intended values; do not have GetConnectionString() depend on derived-constructor-assigned state. |
| Engine selector | DatabaseType enum |
SAIF.NetCore.NHibernate.Options |
Oracle = 0, Sql = 1, PostGreSql = 2. |
| Registration parameters | IServicesCollectionExtensions.AddNhibernateServices(IEnumerable<Assembly>, bool) / AddNhibernateServices<T>(bool) |
SAIF.NetCore.NHibernate.Extensions |
Code-level settings, fixed at registration time and passed to the singleton UnitOfWorkFactory constructor. |
| Options resolution | IOptionsSnapshot<UnitOfWorkOptions>.Get(name) |
Microsoft.Extensions.Options |
UnitOfWorkAccessor.UnitOfWork(key) resolves the named options on every call; it is scoped. |
The library itself makes no IEnvironmentClient member calls, no IConfiguration reads, and no environment-variable reads. It only injects IEnvironmentClient/IDBConnectionClient so that consumer subclasses can call them inside their own GetConnectionString() override.
Library-exposed settings — UnitOfWorkOptions named options¶
One named instance exists per ConfigureUnitOfWorkOptions subclass; the name is the subclass's UniqueName.
| # | Property | Type | Library default | Who sets it | NHibernate / runtime effect | When it takes effect |
|---|---|---|---|---|---|---|
| UO1 | Name |
string |
"default" |
Library, in ConfigureUnitOfWorkOptions.Configure (= UniqueName) |
Key of the per-factory NHibernate configuration cache; copied to IUnitOfWork.Name. |
Every resolution |
| UO2 | Database |
DatabaseType |
Oracle |
Consumer subclass's abstract Database property |
Selects engine configuration (OracleConfiguration/SqlConfiguration/PostGreSqlConfiguration) and the SystemDate session helper. An unrecognized value falls back to Oracle (BR-NH-07) |
Engine configuration: first build per name (cached). Session helper: every unit of work. |
| UO3 | ConnectionString |
string |
null (no default) |
Consumer subclass's abstract GetConnectionString(), called once from the base constructor and cached |
NHibernate connection.connection_string; key of the static, process-wide session-factory cache. Required — GetUnitOfWork throws InvalidOperationException when null/empty (BR-NH-04). Contains credentials. |
First build per connection string (cached for process lifetime) |
| UO4 | BatchSize |
int |
20 |
Consumer override only (not set by the library's configurer) | NHibernate adonet.batch_size |
First build per session-factory key only |
| UO5 | ShowSql |
bool |
true |
Consumer override only | NHibernate show_sql — echoes every generated SQL statement to stdout |
First build per session-factory key only |
| UO6 | DriverFormatSql |
bool |
true |
Consumer override only | FluentNHibernate .FormatSql() on the driver configurer (pretty-printed, multi-line SQL output) |
First build per session-factory key only |
| UO7 | StatelessSessionStrategy |
bool |
false (stateful ISession) |
Consumer override only | true selects IStatelessSession/StatelessSessionStrategy; false selects ISession/StatefulSessionStrategy (BR-NH-10) |
Every unit of work (read per GetUnitOfWork call, not cached) |
Caching caveat: UO4–UO6 are captured only when the session factory is first built for a given connection string, and that factory is cached process-wide. Changing these options after the first unit of work has no effect until the process restarts, and two named instances sharing a connection string also share the first one's
BatchSize/ShowSql/DriverFormatSql.* UO7 and the session-helper part of UO2 are evaluated on every call. Nested-cache mismatch:UO3's session-factory cache (keyed byConnectionString) and the underlying engine-Configurationcache (keyed byName, see Build session factory) are two separate caches with different keys. If two calls share the sameNamebut supply differentConnectionStringvalues, a new session factory IS built (connection-string cache miss), but the reused, name-keyedConfigurationobject'sConnectionStringfield still holds the FIRST connection string ever seen for thatName— so the newly built factory silently connects using the OLD connection string rather than the one just supplied. A new connection-string key does not, by itself, guarantee that the new connection string is actually used end-to-end.
Registration parameters¶
| Parameter | Method | Type | Default | Effect |
|---|---|---|---|---|
assemblyMappings |
AddNhibernateServices(IEnumerable<Assembly>, bool) |
IEnumerable<Assembly> |
none (required) | Assemblies scanned for both Fluent ClassMap<T> and embedded HBM mappings; fixed for the lifetime of the singleton factory. |
T |
AddNhibernateServices<T>(bool) |
type parameter | — | Assembly.GetAssembly(typeof(T)) — resolves to a single mapping assembly. |
debugOutputSql |
Both overloads | bool |
false on the generic overload; required on the IEnumerable<Assembly> overload |
When true, stateful sessions open with SqlDebugOutputInterceptor, which traces SQL to Trace only while a debugger is attached. Stateless sessions never receive it. Independent of ShowSql. |
Override mechanisms for UO4–UO7¶
Unless a consumer applies one of the mechanisms below, the library defaults apply — meaning SQL logging and SQL formatting are on.
| Mechanism | Example | Scope |
|---|---|---|
Override Configure in the subclass |
public override void Configure(string n, UnitOfWorkOptions o) { base.Configure(n, o); if (n == UniqueName) { o.ShowSql = false; } } |
That named database only |
| Register an additional named configure delegate | services.Configure<UnitOfWorkOptions>("myname", o => o.ShowSql = false); |
That named database only |
| Apply to every named instance | services.ConfigureAll<UnitOfWorkOptions>(o => o.ShowSql = false); |
All databases — can also overwrite Name/Database/ConnectionString if misused* |
Bind from IConfiguration (consumer choice) |
services.Configure<UnitOfWorkOptions>("myname", Configuration.GetSection("NHibernate:myname")) |
The library supplies no section name or binding; any appsettings.json keys here are entirely consumer-defined |
Construct UnitOfWorkOptions directly |
new UnitOfWorkOptions { Name = "test", Database = DatabaseType.Oracle, ConnectionString = "<provider-specific connection string>" } passed straight to UnitOfWorkFactory.GetUnitOfWork |
Bypasses the options pipeline entirely |
Environment API settings¶
The library reads no Environment API keys itself. Every IEnvironmentClient key used with this library is consumer-defined inside the subclass's GetConnectionString() override. The rows below are illustrative examples from the test project, not library requirements.
| Setting key (example) | Method | Secure | Purpose | Status |
|---|---|---|---|---|
oracledatabase |
IEnvironmentClient.GetSettingValue(string) |
No | Oracle instance name, passed to IDBConnectionClient.GetOracleConnection(instance, userName) |
Example (test-only, not shipped) |
netframeworksqlserver4 |
GetSettingValue(string) |
No | SQL Server host, passed to GetSqlServerConnection(server, instance, userName) |
Example (test-only) |
Database connection configuration¶
The library is a connection-consumer framework: it defines no connection names or keys of its own. Each consumer defines one connection per ConfigureUnitOfWorkOptions subclass.
| Element | Value |
|---|---|
| Connection identity | The subclass's UniqueName, which becomes the UnitOfWorkOptions name |
| Connection-string source | The consumer's GetConnectionString() override — the standard pattern calls IDBConnectionClient.GetOracleConnection/GetSqlServerConnection/GetPostgreSqlServerConnection |
| Providers | Oracle: Oracle.ManagedDataAccess.Core via OracleManagedDataClientDriver (no native client install needed). SQL Server: NHibernate's default MsSql2008 driver. PostgreSQL: Npgsql via NpgsqlDriver* |
| Resolution timing | Once per configurer construction (base constructor) — in practice once per IOptionsSnapshot scope, i.e. once per request* |
| Caching | Session factory cached process-wide, keyed by the connection string itself; but the nested, name-keyed Configuration cache can reuse a stale connection string if Name collides with a different ConnectionString — see the caching caveat above and Build session factory. |
Secure settings¶
The library reads no secure settings itself. Connection strings (UO3) are secrets but are not configuration keys the library retrieves directly — they are produced by the consumer's GetConnectionString() and then held in UnitOfWorkOptions.ConnectionString, in each configurer's private cached field, and as the key of the static SessionFactories dictionary for the life of the process.
Transitive configuration (from dependencies)¶
Settings a consuming application must supply when it follows the standard ConfigureUnitOfWorkOptions pattern; the library itself has no ProjectReferences.
| Setting / service | Kind | Required | Source dependency | Notes |
|---|---|---|---|---|
IEnvironmentClient registration |
Required service (not registered by this library) | Yes — the configurer constructor requires it | SAIF.NetCore.ServiceContracts (contract); SAIF.NetCore.EnvironmentClient (implementation) |
Usually registered by SAIF.NetCore.ServiceExtensions (CoreAPIStartup). The full bootstrap-key catalog (which keys are mandatory vs. optional, and how the process resolves them) is documented on the owning library's own page: SAIF.NetCore.EnvironmentClient configuration. In summary for this library's own usage: the OS process environment variable EnvironmentApiUrl is mandatory for every host (read once, before the client's constructor body, independent of IConfiguration) — without it, IEnvironmentClient construction fails with MissingEnvironmentUrlVariableException and the consumer's ConfigureUnitOfWorkOptions subclass constructor cannot complete. AppSettings:ApplicationHost/AppSettings:EnvApiDeveloperOverrideAllowed/AppSettings:EnvApiDeveloperSettingsOverride are developer-machine-only optional overrides with no effect on non-developer hosts. When the registered implementation is SecureEnvironmentClient, its constructor requires COREAPIENABLED == "1" or a developer-machine host (IsDeveloperMachine()) merely to construct — this gate is evaluated unconditionally at construction time, regardless of whether any later call through this client resolves a secure or non-secure setting; a non-developer host that fails the gate cannot construct the client at all, so this library's ConfigureUnitOfWorkOptions subclass constructor cannot complete either. Registering a different, non-secure IEnvironmentClient implementation avoids this gate entirely — that is a different implementation choice, not a case of the secure client "only mattering" when secure settings are read. |
IDBConnectionClient registration |
Required service | Yes (constructor) | SAIF.NetCore.ServiceContracts (contract); SAIF.NetCore.DBConnectionClient (implementation) |
Usually registered by SAIF.NetCore.ServiceExtensions. The full endpoint-key catalog is documented on the owning library's own page: SAIF.NetCore.DBConnectionClient configuration. In summary for this library's own usage: ConnectionClient.Setup() reads DBConnectionClient:ServiceUrl, DBConnectionClient:SqlConnectionEndpoint, DBConnectionClient:PostgreSqlConnectionEndpoint, and DBConnectionClient:OracleConnectionEndpoint unconditionally and sequentially, inside the constructor, regardless of which DatabaseType the consumer later uses — there is no engine branch at construction time. This is distinct from later, engine-specific usage: only the matching GetOracleConnection/GetSqlServerConnection/GetPostgreSqlServerConnection call that this library's subclasses actually invoke at runtime uses the corresponding endpoint value. |
IOptionsSnapshot<UnitOfWorkOptions> / options infrastructure |
Required service | Yes | Host (ASP.NET Core / Generic Host registers AddOptions by default) |
Used by UnitOfWorkAccessor |
DBConnectionClient:ServiceUrl, DBConnectionClient:OracleConnectionEndpoint, DBConnectionClient:SqlConnectionEndpoint, DBConnectionClient:PostgreSqlConnectionEndpoint |
Environment API | Required unconditionally at construction | SAIF.NetCore.DBConnectionClient |
All four keys are read by the ConnectionClient constructor for every host, independent of which DatabaseType engine is actually used afterward |
dbconnectionclient:connectionservicecreds |
Secure Environment API setting | Required when ServiceExtensions.RegisterDBConnectionClient registers the client |
SAIF.NetCore.ServiceExtensions |
— |
Configuration dependencies¶
| Dependency | Type | Required at | Impact if missing |
|---|---|---|---|
A ConfigureUnitOfWorkOptions subclass registered for a given name |
Code/DI | Startup, resolved at first use | A UnitOfWorkAccessor.UnitOfWork(key) call for an unregistered name yields default options with no connection string, which throws InvalidOperationException on GetUnitOfWork |
IEnvironmentClient / IDBConnectionClient registration |
DI service | Startup | The consumer subclass's constructor fails to resolve, which fails DI container validation/first resolution |
Valid connection-string resolution in GetConnectionString() |
Runtime | First options resolution per name | An exception there surfaces when the options are first resolved, before any session work begins |
Related documentation¶
- Index
- Overview
- Architecture
- Dependencies
- Operations and processes
- Business rules
- Database tables
- SQL catalog
- Service registration
- API reference
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/Options/UnitOfWorkOptions.cssrc/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Options/ConfigureUnitOfWorkOptions.cssrc/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Options/DatabaseType.cssrc/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Extensions/IServicesCollectionExtensions.cssrc/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Factories/UnitOfWorkFactory.cssrc/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Factories/Configuration/BaseConfiguration.cssrc/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWorkAccessor.cssrc/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate.Tests/Options/ConfigureOracleUnitOfWork.cs(test-fixture example of aConfigureUnitOfWorkOptionssubclass)src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate.Tests/Options/ConfigureSqlUnitOfWork.cs(test-fixture example of aConfigureUnitOfWorkOptionssubclass)