Skip to main content

PostgreSQL Provider

The PostgreSQL provider offers full relational database support with Npgsql-based query execution, event sourcing integration, inbox/outbox patterns, and Change Data Capture.

Before You Start​

Installation​

dotnet add package Excalibur.Data.Postgres

Dependencies: Excalibur.Data.Abstractions, Npgsql

Quick Start​

using Microsoft.Extensions.DependencyInjection;

services.AddPostgresDataExecutors(() => new NpgsqlConnection(connectionString));

Registration Methods​

MethodWhat It RegistersKey Options
data.UsePostgres(Action<IPostgresDataBuilder>)Core data executorsBuilder with 5 connection overloads
es.UsePostgres(Action<IPostgresEventSourcingBuilder>)IEventStore + ISnapshotStoreBuilder with 5 connection overloads
saga.UsePostgres(Action<IPostgresSagaBuilder>)ISagaStoreBuilder with 5 connection + SchemaName, TableName
inbox.UsePostgres(Action<IPostgresInboxBuilder>)IInboxStoreBuilder with 5 connection + SchemaName, TableName, MaxRetryCount
outbox.UsePostgres(Action<IPostgresOutboxBuilder>)IOutboxStoreBuilder with 5+ connection + SchemaName, TableName, DeadLetterTableName
le.UsePostgres(Action<IPostgresLeaderElectionBuilder>)ILeaderElectionBuilder with 5 connection + LockKey
cdc.UsePostgres(Action<IPostgresCdcBuilder>)CDC processorBuilder with 5 connection + PublicationName, ReplicationSlotName
compliance.UsePostgres(Action<IPostgresComplianceBuilder>)Erasure + DataInventory + LegalHoldBuilder with 5 connection overloads
AddPostgresAuditStore(Action<PostgresAuditOptions>) / AddPostgresAuditStore(IConfiguration)IAuditStorePostgresAuditOptions (connection, schema, table)
AddPostgresProjectionStore<T>(opts)IProjectionStore<T>ConnectionString, TableName

The event store writes each event's declared [MessageName] -- not its CLR type name -- to the stored event-type field, and resolves that name back to a CLR type through the registered event-type registry on read. See Stable Message Names.

Batch Projection Registration​

Register multiple projections sharing the same connection:

services.AddPostgresProjections(connectionString, projections =>
{
projections.Add<OrderSummary>();
projections.Add<CustomerProfile>(o => o.TableName = "customer_views");
});

Change Data Capture​

services.AddCdcProcessor(cdc =>
{
cdc.UsePostgres(pg => pg.ConnectionString(connectionString))
.TrackTable("public.orders", t => t.MapAll<OrderChangedEvent>());
});

Data Request Pattern​

public class GetCustomerRequest : DataRequest<Customer?>
{
public GetCustomerRequest(Guid customerId)
{
Command = new CommandDefinition(
"SELECT * FROM customers WHERE id = @Id",
new { Id = customerId });
}
}

See Also​