dotnet-cqrs/Svrnty.Sample/session-summary.md

3.5 KiB

Session Summary - Phase 8 PostgreSQL DI Fix

Date

2025-12-10

Issue Fixed

Fixed a dependency injection configuration bug in AddPostgresSchemaStore() that prevented the application from starting.

Problem

The PostgresSchemaStore constructor requires two string parameters (connectionString and schemaName), but the service registration was attempting to register it directly as a singleton without providing these parameters:

// BEFORE (broken):
public static IServiceCollection AddPostgresSchemaStore(this IServiceCollection services)
{
    services.Replace(ServiceDescriptor.Singleton<ISchemaStore, PostgresSchemaStore>());
    return services;
}

This caused a runtime error:

System.InvalidOperationException: Unable to resolve service for type 'System.String'
while attempting to activate 'Svrnty.CQRS.Events.PostgreSQL.PostgresSchemaStore'.

Solution

Updated the registration to use a factory method that retrieves the connection string and schema name from PostgresEventStreamStoreOptions:

// AFTER (fixed):
public static IServiceCollection AddPostgresSchemaStore(this IServiceCollection services)
{
    services.Replace(ServiceDescriptor.Singleton<ISchemaStore>(sp =>
    {
        var options = sp.GetRequiredService<IOptions<PostgresEventStreamStoreOptions>>().Value;
        var logger = sp.GetRequiredService<ILogger<PostgresSchemaStore>>();
        return new PostgresSchemaStore(options.ConnectionString, options.SchemaName, logger);
    }));

    return services;
}

File Changed

  • /Users/mathias/Documents/workspaces/svrnty/dotnet-cqrs/Svrnty.CQRS.Events.PostgreSQL/ServiceCollectionExtensions.cs (lines 294-309)

Verification

  1. Solution compiles with 0 errors
  2. Application starts successfully (using in-memory storage for testing)
  3. gRPC services are accessible
  4. Commands execute successfully (tested AddUser command)
  5. Phase 8 infrastructure is registered and running:
    • SignalR Hub: ws://localhost:6001/hubs/subscriptions
    • Event Stream Hub: ws://localhost:6001/hubs/events
    • Subscription storage: In-memory
    • Background delivery: Enabled

Configuration Changes

For testing purposes, updated appsettings.json:

  • Set EventStreaming:UsePostgreSQL to false (use in-memory storage)
  • Set EventStreaming:RabbitMQ:Enabled to false (no RabbitMQ server running)

Current Status

  • Phase 8 (Bidirectional Communication & Persistent Subscriptions) is fully integrated
  • All dependencies are properly configured
  • Application runs without errors
  • ⚠️ Sample invitation workflow is disabled (pending IEventPublisher implementation)
  • ⚠️ Background delivery service is disabled (pending ICorrelatedEvent.Sequence property)

Next Steps (Optional)

  1. Implement or identify the IEventPublisher interface for automatic event delivery
  2. Add event sequence tracking to ICorrelatedEvent or create wrapper type
  3. Re-enable and test SubscriptionDeliveryHostedService
  4. Restore invitation workflow sample code
  5. Test persistent subscriptions end-to-end with SignalR clients

Testing

The application is currently running on:

Available services:

  • cqrs.CommandService
  • cqrs.QueryService
  • cqrs.DynamicQueryService
  • svrnty.cqrs.events.EventService

Test command:

grpcurl -plaintext -d '{"name": "Alice", "email": "alice@example.com", "age": 30}' \
  localhost:6000 cqrs.CommandService/AddUser

Result: Successfully created user with ID 202