Veggerby.Ignition.Postgres
0.6.0
dotnet add package Veggerby.Ignition.Postgres --version 0.6.0
NuGet\Install-Package Veggerby.Ignition.Postgres -Version 0.6.0
<PackageReference Include="Veggerby.Ignition.Postgres" Version="0.6.0" />
<PackageVersion Include="Veggerby.Ignition.Postgres" Version="0.6.0" />
<PackageReference Include="Veggerby.Ignition.Postgres" />
paket add Veggerby.Ignition.Postgres --version 0.6.0
#r "nuget: Veggerby.Ignition.Postgres, 0.6.0"
#:package Veggerby.Ignition.Postgres@0.6.0
#addin nuget:?package=Veggerby.Ignition.Postgres&version=0.6.0
#tool nuget:?package=Veggerby.Ignition.Postgres&version=0.6.0
Veggerby.Ignition.Postgres
PostgreSQL readiness signals for Veggerby.Ignition - verify database connections and schema during application startup.
Installation
dotnet add package Veggerby.Ignition.Postgres
dotnet add package Npgsql
Usage
Modern Pattern: NpgsqlDataSource (Recommended)
The recommended approach uses NpgsqlDataSource for better connection pooling and DI integration:
// Register NpgsqlDataSource in DI container
builder.Services.AddNpgsqlDataSource(
"Host=localhost;Database=mydb;Username=user;Password=pass");
// Add PostgreSQL readiness signal (automatically resolves NpgsqlDataSource from DI)
builder.Services.AddIgnition();
builder.Services.AddPostgresReadiness();
var app = builder.Build();
await app.Services.GetRequiredService<IIgnitionCoordinator>().WaitAllAsync();
Why NpgsqlDataSource?
- Better connection pooling: Modern Npgsql 7.0+ recommended pattern
- Cleaner DI integration: No connection string duplication
- Multiplexing support: Enables advanced pooling scenarios
- Shared across services: Same data source used by repositories/DbContext
Legacy Pattern: Connection String
For simpler scenarios or when NpgsqlDataSource isn't registered in DI:
builder.Services.AddIgnition();
builder.Services.AddPostgresReadiness(
"Host=localhost;Database=mydb;Username=user;Password=pass");
var app = builder.Build();
await app.Services.GetRequiredService<IIgnitionCoordinator>().WaitAllAsync();
With Validation Query
builder.Services.AddNpgsqlDataSource(connectionString);
builder.Services.AddPostgresReadiness(options =>
{
options.ValidationQuery = "SELECT 1";
options.Timeout = TimeSpan.FromSeconds(5);
});
Advanced Schema Validation
builder.Services.AddNpgsqlDataSource(connectionString);
builder.Services.AddPostgresReadiness(options =>
{
// Verify specific table exists
options.ValidationQuery = "SELECT 1 FROM users LIMIT 1";
options.Timeout = TimeSpan.FromSeconds(10);
});
Features
- Connection Verification: Validates database connectivity
- Optional Query Validation: Execute custom queries to verify schema readiness
- Activity Tracing: Tags for server, database, and validation queries
- Structured Logging: Information, Debug, and Error level diagnostics
- Idempotent Execution: Cached results prevent redundant connection attempts
- Thread-Safe: Concurrent readiness checks execute once
Configuration Options
| Property | Type | Description | Default |
|---|---|---|---|
Timeout |
TimeSpan? |
Per-signal timeout override | null (uses global timeout) |
ValidationQuery |
string? |
SQL query to execute after connection | null (connection only) |
Logging
The signal emits structured logs at different levels:
- Information: Connection attempts and successful completions
- Debug: Connection established, validation query execution
- Error: Connection failures, query execution failures
Activity Tracing
When tracing is enabled, the signal adds these tags:
postgres.server: Host from connection stringpostgres.database: Database name from connection stringpostgres.validation_query: Validation query if configured
Examples
Health Check Integration
builder.Services.AddIgnition();
builder.Services.AddPostgresReadiness(connectionString);
builder.Services
.AddHealthChecks()
.AddCheck<IgnitionHealthCheck>("ignition-readiness");
Multiple Databases
With NpgsqlDataSource (when you have multiple databases):
// Primary database
builder.Services.AddNpgsqlDataSource(
primaryConnectionString,
serviceKey: "primary");
// Read replica
builder.Services.AddNpgsqlDataSource(
replicaConnectionString,
serviceKey: "replica");
// Note: Currently AddPostgresReadiness only supports the default (non-keyed) data source.
// For multiple databases, register custom signals manually:
builder.Services.AddIgnitionSignal(sp =>
{
var primaryDs = sp.GetRequiredKeyedService<NpgsqlDataSource>("primary");
var logger = sp.GetRequiredService<ILogger<PostgresReadinessSignal>>();
return new PostgresReadinessSignal(primaryDs, new PostgresReadinessOptions
{
ValidationQuery = "SELECT 1",
Timeout = TimeSpan.FromSeconds(5)
}, logger);
});
builder.Services.AddIgnitionSignal(sp =>
{
var replicaDs = sp.GetRequiredKeyedService<NpgsqlDataSource>("replica");
var logger = sp.GetRequiredService<ILogger<PostgresReadinessSignal>>();
return new PostgresReadinessSignal(replicaDs, new PostgresReadinessOptions
{
ValidationQuery = "SELECT 1",
Timeout = TimeSpan.FromSeconds(10)
}, logger);
});
With connection strings (simpler for multiple databases):
// Primary database
builder.Services.AddPostgresReadiness(
primaryConnectionString,
options =>
{
options.ValidationQuery = "SELECT 1";
options.Timeout = TimeSpan.FromSeconds(5);
});
// Read replica
builder.Services.AddPostgresReadiness(
replicaConnectionString,
options =>
{
options.ValidationQuery = "SELECT 1";
options.Timeout = TimeSpan.FromSeconds(10);
});
Note: Multiple PostgreSQL signals will share the same name ("postgres-readiness"). For distinct signal names, implement custom IIgnitionSignal instances.
Error Handling
Connection failures and query execution errors are logged and propagated:
try
{
await coordinator.WaitAllAsync();
}
catch (AggregateException ex)
{
foreach (var inner in ex.InnerExceptions)
{
if (inner is NpgsqlException pgEx)
{
// Handle PostgreSQL-specific errors
Console.WriteLine($"PostgreSQL Error: {pgEx.Message}");
}
}
}
Performance
- Minimal allocations per signal invocation
- Connection pooling handled by Npgsql
- Async throughout (no blocking I/O)
- Idempotent execution (connection attempted once)
License
MIT License. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Options (>= 10.0.1)
- Npgsql (>= 9.0.3)
- Veggerby.Ignition (>= 0.6.0)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Options (>= 10.0.1)
- Npgsql (>= 9.0.3)
- Veggerby.Ignition (>= 0.6.0)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Options (>= 10.0.1)
- Npgsql (>= 9.0.3)
- Veggerby.Ignition (>= 0.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.6.0 | 95 | 2/2/2026 |
| 0.5.1-prerelease0023 | 94 | 2/2/2026 |
| 0.5.1-prerelease0022 | 90 | 1/26/2026 |
| 0.5.1-prerelease0021 | 90 | 1/22/2026 |
| 0.5.1-prerelease0020 | 94 | 1/22/2026 |
| 0.5.1-prerelease0019 | 92 | 1/21/2026 |
| 0.5.1-prerelease0018 | 88 | 1/21/2026 |
| 0.5.1-prerelease0017 | 87 | 1/20/2026 |
| 0.5.1-prerelease0016 | 91 | 1/20/2026 |
| 0.5.1-prerelease0014 | 91 | 1/20/2026 |
| 0.5.1-prerelease0013 | 87 | 1/20/2026 |
| 0.5.1-prerelease0011 | 85 | 1/19/2026 |
| 0.5.1-prerelease0009 | 95 | 1/19/2026 |
| 0.5.1-prerelease0008 | 92 | 1/17/2026 |
| 0.5.1-prerelease0007 | 89 | 1/16/2026 |
| 0.5.1-prerelease0006 | 93 | 1/16/2026 |
| 0.5.1-prerelease0004 | 99 | 1/16/2026 |
| 0.5.1-prerelease0003 | 91 | 1/15/2026 |
| 0.5.1-prerelease0002 | 95 | 1/15/2026 |
| 0.5.1-prerelease0001 | 95 | 1/15/2026 |