Skip to content

[Maintainability] Servy.Restarter/Program.cs — AppDbContext created but never disposed #792

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Info
File: src/Servy.Restarter/Program.cs line 121 (created), finally block lines 152-159 (disposal site)

Description:

Program.Main creates an AppDbContext and three other disposables:

// 5. Initialize database and helpers
var dbContext = new AppDbContext(connectionString);                      // line 121 — IDisposable, never disposed

var dapperExecutor = new DapperExecutor(dbContext);
var protectedKeyProvider = new ProtectedKeyProvider(aesKeyFilePath, aesIVFilePath);
secureData = new SecureData(protectedKeyProvider);
...
}
catch (Exception ex)
{
    (scopedLogger ?? rootLogger).Error($"Servy.Restarter.exe failed to restart the service: {ex.Message}", ex);
    Environment.ExitCode = 1;
}
finally
{
    // Clean up
    secureData?.Dispose();
    scopedLogger?.Dispose();
    rootLogger.Dispose();
    Logger.Shutdown();                                                    // dbContext NOT disposed
}

AppDbContext implements IDisposable with the standard pattern (Dispose(bool), ThrowIfDisposed, _disposed flag). Today Dispose() is effectively a no-op — the class holds only a connection string — so there is no observable leak right now.

The concern is future-proofing: src/Servy.Infrastructure/Data/AppDbContext.cs explicitly anticipates resources being added later:

protected virtual void Dispose(bool disposing)
{
    if (_disposed) return;

    if (disposing)
    {
        // Release managed resources if any are added in the future 
        // (e.g., a shared DbConnection or a CancellationSource)
    }

    _disposed = true;
}

The moment someone adds a shared connection or cancellation source there — which the comment invites — this call site will leak it silently. The caller already cares about disposing the other three disposables; adding dbContext to the finally block is the minimal-friction fix.

Suggested fix:

AppDbContext? dbContext = null;
...
try
{
    ...
    // 5. Initialize database and helpers
    dbContext = new AppDbContext(connectionString);
    ...
}
catch (Exception ex) { ... }
finally
{
    secureData?.Dispose();
    scopedLogger?.Dispose();
    rootLogger.Dispose();
    dbContext?.Dispose();   // <-- add this
    Logger.Shutdown();
}

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions