Skip to content

MigrationGuide

Brian Lehnen edited this page Apr 9, 2026 · 2 revisions

Migration Guide

This guide covers breaking changes from version 0.8.0 through 0.9.31, organized chronologically. Find your current version and read all sections that follow it.


0.8.0 -- SQL Client Change

The SQL Server transport switched from System.Data.SqlClient to Microsoft.Data.SqlClient.

Before:

<PackageReference Include="System.Data.SqlClient" Version="..." />

After:

<PackageReference Include="Microsoft.Data.SqlClient" Version="..." />

Connection strings are mostly compatible. One behavioral difference: Microsoft.Data.SqlClient defaults to Encrypt=True, whereas System.Data.SqlClient defaulted to Encrypt=False. If you connect to a SQL Server instance without a trusted certificate, add Encrypt=False;TrustServerCertificate=True; to your connection string or configure the server certificate appropriately.


0.9.1 -- Metrics Migration

App.Metrics was replaced with the built-in System.Diagnostics.Metrics API. The DotNetWorkQueue.AppMetrics NuGet package was removed.

Before:

// Add App.Metrics NuGet packages and configure:
var metrics = new MetricsBuilder().Build();
services.AddMetrics(metrics);

After:

// Use OpenTelemetry.Metrics (or any System.Diagnostics.Metrics exporter):
services.AddOpenTelemetry()
    .WithMetrics(builder => builder
        .AddMeter("DotNetWorkQueue")
        .AddPrometheusExporter());

Additional API changes:

  • SamplingTypes enum removed -- it was a parameter on IMetrics.Histogram() and IMetrics.Timer(). Remove any references to SamplingTypes from your code.
  • dynamic CollectedMetrics replaced with strongly typed MetricsSnapshot GetCollectedMetrics(). Update any code that called GetCollectedMetrics() to use the MetricsSnapshot type.

See Metrics and Monitoring for current usage.


0.9.13 -- Thread.Abort Removal

AbortWorkerThreadsWhenStopping was removed from IWorkerConfiguration. Worker shutdown now relies exclusively on cooperative cancellation via CancellationToken.

Before:

configuration.Worker.AbortWorkerThreadsWhenStopping = true;

After:

// Remove the line above entirely.
// Control shutdown timing with:
configuration.Worker.TimeToWaitForWorkersToCancel = TimeSpan.FromSeconds(5);
configuration.Worker.TimeToWaitForWorkersToStop = TimeSpan.FromSeconds(10);

Workers that do not respond to cancellation within the configured windows will be abandoned rather than aborted. Ensure your message handlers observe the CancellationToken passed to them.

Thread.Sleep in internal worker loops was replaced with ManualResetEventSlim for more responsive cancellation.

See WorkerConfiguration for all shutdown timing options.


0.9.19 -- .NET Framework Drop and Dynamic LINQ Removal

Two removals in this release:

.NET Target Framework Changes

.NET Framework 4.8 and .NET Standard 2.0 targets were dropped. The library now targets .NET 8.0 and .NET 10.0 only. Update your project's <TargetFramework> (or <TargetFrameworks>) to net8.0 or net10.0.

All #if NETFULL and #if NETSTANDARD2_0 conditional compilation blocks were removed from the library source.

Dynamic LINQ Removal

String-based dynamic LINQ expressions (LinqExpressionToRun) were removed. This feature was only available on .NET Framework 4.8 via JpLabs.DynamicCode.

Before:

producer.Send(new LinqExpressionToRun(
    "(message, workerNotification) => new SimpleMessageMethod().Handle((SimpleMessage)message.Body, workerNotification)",
    new[] { "MyAssembly.dll" }
));

After:

// Use a compiled lambda with ActionMethodReceiver:
producer.Send<SimpleMessageMethod, SimpleMessage>(message);

See ProducerMethod for the current method-based producer API.


0.9.30 -- Schyntax to Cron Migration

The Schyntax schedule format was replaced with standard cron expressions via Cronos. All schedule strings in heartbeat configuration and the job scheduler must be updated.

Supported formats:

Format Example Granularity
5-field cron * * * * * Minute
6-field cron (with seconds) * * * * * * Second

Before:

// Schyntax format
jobScheduler.AddUpdateJob<SimpleMessage>("my-job", queue, "seconds(0/5)");

After:

// Cron format -- every 5 seconds (6-field)
jobScheduler.AddUpdateJob<SimpleMessage>("my-job", queue, "*/5 * * * * *");

// Or every minute (5-field)
jobScheduler.AddUpdateJob<SimpleMessage>("my-job", queue, "* * * * *");

IJobSchedule API Changes

  • IJobSchedule.Previous() return type changed from DateTimeOffset to DateTimeOffset?. Update callers to handle null (null means the job has never run).

Before:

DateTimeOffset prev = schedule.Previous();

After:

DateTimeOffset? prev = schedule.Previous();
if (prev.HasValue) { /* use prev.Value */ }
  • IJobSchedule.Description is a new property that returns a human-readable description of the cron expression.

All heartbeat configuration strings that previously used Schyntax format must also be updated to cron format.

See Scheduler and JobScheduler for current scheduling documentation.


0.9.31 -- Multi-Source Dashboard Config

The Dashboard UI configuration changed from a flat DashboardApi:BaseUrl / DashboardApi:ApiKey format to a DashboardApi:Sources[] array. The old format throws an InvalidOperationException at startup with a migration example.

Before:

{
  "DashboardApi": {
    "BaseUrl": "http://localhost:5000",
    "ApiKey": "my-key"
  }
}

After:

{
  "DashboardApi": {
    "Sources": [
      {
        "Name": "Local",
        "BaseUrl": "http://localhost:5000",
        "ApiKey": "my-key"
      }
    ]
  }
}

Each source entry requires a Name (used as the display label and to derive the URL slug), BaseUrl, and an optional ApiKey. Add multiple entries to connect one UI deployment to separate Dashboard API instances.

URL Routing Change

All page URLs now include a /source/{slug} prefix (e.g., /source/local/connections/{id}). Single-source deployments redirect automatically from / to the source view.

Self-Contained / Docker Mode

In self-contained mode, the in-process API auto-registers as a "Local" source. You do not need to add a Sources entry for it. Remove the old DashboardApi:BaseUrl and DashboardApi:ApiKey keys after migration.

See Dashboard UI and Dashboard Docker Deployment for full configuration details.

Clone this wiki locally