Dependency injection and logging

Resolve the runner and migration dependencies inside one service scope.

Examples use Classic and Fluent tabs. Your choice follows you through the manual.

Register the integration

Install DotNetProjects.Migrator.Extensions.DependencyInjection and Microsoft.Extensions.Logging alongside the core and database driver. This example uses the connection-string provider factory so provider disposal belongs to the DI scope. The providerName explicitly selects the SQLite driver.

A scoped migration host

Classic

using DotNetProjects.Migrator;
using DotNetProjects.Migrator.Providers;
using DotNetProjects.Migrator.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddLogging();
services.AddMigrator(_ => ProviderFactory.Create(
    ProviderTypes.SQLite, "Data Source=app.db", defaultSchema: null,
    providerName: "Microsoft.Data.Sqlite"), typeof(CreateUsers).Assembly,
    options => options.TransactionMode = MigrationTransactionMode.PerMigration);

using var container = services.BuildServiceProvider();
using var scope = container.CreateScope();
scope.ServiceProvider.GetRequiredService<Migrator>().MigrateToLastVersion();

Fluent

using DotNetProjects.Migrator;
using DotNetProjects.Migrator.Providers;
using DotNetProjects.Migrator.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddLogging();
services.AddMigrator(_ => ProviderFactory.Create(
    ProviderTypes.SQLite, "Data Source=app.db", defaultSchema: null,
    providerName: "Microsoft.Data.Sqlite"), typeof(CreateUsers).Assembly,
    options => options.TransactionMode = MigrationTransactionMode.PerMigration);

using var container = services.BuildServiceProvider();
using var scope = container.CreateScope();
scope.ServiceProvider.GetRequiredService<Migrator>().MigrateToLastVersion();

Shared host · both styles

Constructor dependencies

Migration classes are registered for activation through the service provider. Register your own constructor dependencies before resolving the runner. Options are scoped snapshots; a custom Activator can override construction. Fluent and Classic migrations use the same activation mechanism.

Logging boundaries

The integration adapts runner lifecycle events to Microsoft logging. It omits SQL text and raw exception messages from these events. Configure your own logging providers through AddLogging. The core retains its lightweight logger API when you do not use DI.

Dispose the scope after migration execution. When supplying a caller-owned open connection, keep its owner alive until after the scope is disposed; the provider does not acquire ownership of an externally supplied connection.