Class NpgsqlDbContextFactory
Factory for creating NpgsqlDbContext instances. Thread-safe and intended for singleton registration. Implements IDesignTimeDbContextFactory<TContext> for EF Core tooling.
public class NpgsqlDbContextFactory : INpgsqlDbContextFactory, IDbContextFactory, IDisposable, IAsyncDisposable, IDbContextFactoryMonitoring, IDesignTimeDbContextFactory<NpgsqlDbContext>
- Inheritance
-
NpgsqlDbContextFactory
- Implements
- Inherited Members
- Extension Methods
Constructors
NpgsqlDbContextFactory()
Initializes a new instance of NpgsqlDbContextFactory for EF Core design-time usage. Loads configuration from the current AppDomain base directory.
public NpgsqlDbContextFactory()
NpgsqlDbContextFactory(NpgsqlDbConfiguration)
Initializes a new instance of NpgsqlDbContextFactory with a pre-built configuration.
public NpgsqlDbContextFactory(NpgsqlDbConfiguration configuration)
Parameters
configurationNpgsqlDbConfigurationThe database configuration.
Exceptions
- ArgumentNullException
Thrown when configuration is null.
NpgsqlDbContextFactory(IConfiguration)
Initializes a new instance of NpgsqlDbContextFactory from a pre-built IConfiguration.
public NpgsqlDbContextFactory(IConfiguration configuration)
Parameters
configurationIConfigurationConfiguration root containing an
Npgsqlsection.
Exceptions
- ArgumentNullException
Thrown when
configurationisnull.
NpgsqlDbContextFactory(IConfiguration, bool)
Initializes a new instance of NpgsqlDbContextFactory from a pre-built IConfiguration.
public NpgsqlDbContextFactory(IConfiguration configuration, bool enableLogging)
Parameters
configurationIConfigurationConfiguration root containing an
Npgsqlsection.enableLoggingboolEnable sensitive data logging for development.
Exceptions
- ArgumentNullException
Thrown when
configurationisnull.
NpgsqlDbContextFactory(IConfiguration, bool, int)
Initializes a new instance of NpgsqlDbContextFactory from a pre-built IConfiguration.
public NpgsqlDbContextFactory(IConfiguration configuration, bool enableLogging, int commandTimeout)
Parameters
configurationIConfigurationConfiguration root containing an
Npgsqlsection.enableLoggingboolEnable sensitive data logging for development.
commandTimeoutintCommand timeout in seconds (overrides config file value).
Exceptions
- ArgumentNullException
Thrown when
configurationisnull.
Properties
ActiveContextCount
Gets the current number of active (not yet disposed) DbContext instances.
public int ActiveContextCount { get; }
Property Value
MaxPoolSize
Gets the configured maximum pool size.
public int MaxPoolSize { get; }
Property Value
PerformanceTracker
Gets the query performance tracker for operation-level monitoring.
public QueryPerformanceTracker PerformanceTracker { get; }
Property Value
PoolMetrics
Gets the connection pool metrics for monitoring and diagnostics.
public ConnectionPoolMetrics PoolMetrics { get; }
Property Value
RetryPolicy
Gets the retry policy configuration for transient failure handling.
public RetryPolicyConfiguration RetryPolicy { get; }
Property Value
Methods
CanConnectAsync(CancellationToken)
Tests whether the database is reachable. Useful for startup validation or health checks.
public Task<bool> CanConnectAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenCancellation token.
Returns
CreateDbContext()
Creates a new DbContext instance. Thread-safe. Each call creates a fresh context with new options - safe for concurrent use. The factory tracks active contexts for graceful shutdown support.
public NpgsqlDbContext CreateDbContext()
Returns
- NpgsqlDbContext
A new NpgsqlDbContext instance.
CreateDbContext(string[])
IDesignTimeDbContextFactory implementation for EF Core migrations. Used by dotnet ef commands for database migrations.
public NpgsqlDbContext CreateDbContext(string[] args)
Parameters
argsstring[]Command line arguments from migration tools.
Returns
- NpgsqlDbContext
A new NpgsqlDbContext instance.
CreateDbContextAsync(CancellationToken)
Asynchronously creates a new DbContext instance. DbContext creation is CPU-bound, not I/O-bound, so this returns a completed task. The cancellation token is checked before context creation.
public Task<NpgsqlDbContext> CreateDbContextAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenCancellation token.
Returns
- Task<NpgsqlDbContext>
A new NpgsqlDbContext instance.
Exceptions
- OperationCanceledException
Thrown if cancellation is requested.
Dispose()
Disposes the factory and releases all resources. Calls Shutdown() to reject new context creation, waits briefly for active contexts to complete, then disposes monitoring resources.
public void Dispose()
Remarks
This method will wait up to 5 seconds for active contexts to be disposed before proceeding. For longer waits, use ShutdownGracefullyAsync(TimeSpan, CancellationToken) before calling Dispose.
DisposeAsync()
Asynchronously disposes the factory and releases all resources. Calls Shutdown() to reject new context creation, waits briefly for active contexts to complete, then disposes monitoring resources.
public ValueTask DisposeAsync()
Returns
- ValueTask
A ValueTask representing the asynchronous dispose operation.
Shutdown()
Shuts down the factory and rejects new DbContext creation. Unity-friendly synchronous shutdown (safe to call from main thread).
public void Shutdown()
ShutdownAsync(CancellationToken)
Initiates shutdown and returns immediately without waiting for active DbContext instances to complete.
This method sets the shutdown flag (which causes CreateDbContext() to throw ObjectDisposedException for future calls) and returns CompletedTask without waiting for active contexts to drain. This is a non-graceful shutdown — active queries or transactions on existing contexts will continue until those contexts are disposed by their owners, but no new contexts can be created.
Callers that require a graceful shutdown (waiting for all active contexts to complete) should use ShutdownGracefullyAsync(TimeSpan, CancellationToken) with an appropriate timeout instead.
public Task ShutdownAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenA cancellation token to observe while initiating shutdown.
Returns
- Task
A task that completes immediately after the shutdown flag is set.
ShutdownGracefullyAsync(TimeSpan, CancellationToken)
Initiates shutdown and waits for all active contexts to be disposed.
public Task<bool> ShutdownGracefullyAsync(TimeSpan timeout, CancellationToken cancellationToken = default)
Parameters
timeoutTimeSpanMaximum time to wait for active contexts to complete.
cancellationTokenCancellationTokenCancellation token.
Returns
TryConnectAsync(CancellationToken)
Tests whether the database is reachable, reporting why when it is not.
public Task<(bool Connected, string? FailureReason)> TryConnectAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenCancellation token.
Returns
- Task<(bool Connected, string FailureReason)>
Whether the connection succeeded, and the failure reason when it did not.
Remarks
CanConnectAsync(CancellationToken) collapses every cause into false: a wrong password
(SQLSTATE 28000), an unreachable host, an exhausted pool, and a factory that has
already shut down are indistinguishable to its caller. That turns a five-second fix
into an outage spent checking the network, so the reason is preserved here for callers
that report to an operator. Never throws.
ValidateSchemaAsync(CancellationToken)
Reports whether this database has applied every migration the entity model expects.
public Task<SchemaValidationResult> ValidateSchemaAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenCancellation token.
Returns
- Task<SchemaValidationResult>
What was found. Never throws.
Remarks
Migrations are generated per developer and applied locally rather than shared through source control, so pulling a change to an entity does not bring a migration with it and nothing applies one on your behalf. The database simply stays where it was, and the first symptom is a query failing at runtime for a column that does not exist — which surfaces far from the cause, as missing data rather than as a schema problem.
This catches one of the two ways that happens: pending migrations, where the
migration exists and this database has not run it. Fix with
dotnet ef database update.
It does not catch model drift — an entity changed with no migration
generated for it, which leaves nothing pending and a schema that is quietly wrong. A
drift check lived here and never worked once: it compared the migration snapshot's
model against the live one, but EF builds ModelSnapshot.Model with an empty
convention set, so GetRelationalModel() threw on every startup. EF Core 5 has no
supported way to rebuild that model at runtime, so the check was removed rather than
left reporting a failure forever. See issue #162; drift belongs in CI, where a
scaffolded migration can be asserted empty.