Skip to content

Latest commit

 

History

History
289 lines (205 loc) · 8.12 KB

File metadata and controls

289 lines (205 loc) · 8.12 KB

DBMigrator Aspire Integration - Implementation Summary

Overview

I've successfully created a .NET Aspire integration for DBMigrator that allows automatic database migrations to run as part of the Aspire application lifecycle.

What Was Created

1. Core Integration Package: DBMigrator.Aspire.Hosting

This package provides the Aspire hosting integration:

Location: DBMigrator.Aspire.Hosting/

Files Created:

  • DBMigrator.Aspire.Hosting.csproj - Project file
  • DBMigratorResource.cs - Resource implementation
  • DBMigratorResourceBuilderExtensions.cs - Fluent API for configuration
  • DBMigratorAnnotations.cs - Configuration annotations
  • DBMigratorLifecycleHook.cs - Lifecycle hook for execution
  • DBMigratorHostingExtensions.cs - Service registration
  • README.md - Package documentation
  • ARCHITECTURE.md - Technical architecture documentation
  • NuGet.config - Package source configuration

2. Example Project: DBMigrator.Aspire.Example

A complete working example showing how to use the integration:

Location: Examples/DBMigrator.Aspire.Example/

Files Created:

  • DBMigrator.Aspire.Example.csproj - Example AppHost project
  • Program.cs - Example configuration
  • appsettings.json - Logging configuration
  • README.md - Example documentation
  • Sample migration scripts in Migrations/1.0/UserManagement/Migrations/

3. Test Project: DBMigrator.Aspire.Tests

Unit tests for the integration:

Location: DBMigrator.Aspire.Tests/

Files Created:

  • DBMigrator.Aspire.Tests.csproj - Test project
  • DBMigratorResourceBuilderExtensionsTests.cs - Unit tests

4. Updated Documentation

  • Updated main README.md with Aspire integration section
  • Created comprehensive architecture documentation

Key Features

Fluent API

var builder = DistributedApplication.CreateBuilder(args);

var sqlServer = builder.AddSqlServer("sql");
var database = sqlServer.AddDatabase("mydb");

var dbMigrator = builder.AddDBMigrator("dbmigrator", database, "./Migrations")
    .WithTargetVersion("2.0")     // Optional: target specific version
    .WithSkipValidation()          // Optional: skip validation
    .WithDryRun();                 // Optional: test without committing

builder.AddDBMigratorLifecycleHook();

var api = builder.AddProject<Projects.MyApi>("api")
    .WaitForDBMigrator(dbMigrator); // Wait for migrations

builder.Build().Run();

Automatic Execution

  • Migrations run automatically before application starts
  • Integrates with Aspire's lifecycle hooks
  • Waits for SQL Server to be ready
  • Reports success/failure through logging

Configuration Options

  • Target Version: Migrate to specific version or latest
  • Skip Validation: Skip database integrity checks
  • Dry Run: Test migrations without committing
  • Dependency Management: Other resources can wait for migrations

Architecture Highlights

Design Pattern

  • Uses IDistributedApplicationLifecycleHook for execution
  • Implements IResource and IResourceWithConnectionString
  • Annotations pattern for configuration
  • Fluent API for developer experience

Execution Flow

  1. Application starts ? Aspire initializes resources
  2. SQL Server container starts
  3. DBMigratorLifecycleHook.BeforeStartAsync() triggered
  4. Wait for SQL Server readiness
  5. Load configuration from annotations
  6. Connect to database and read migration scripts
  7. Calculate pending migrations
  8. Validate database (if not skipped)
  9. Execute migrations
  10. Log results
  11. Application resources start

Error Handling

  • Migration failures prevent application startup
  • Clear error messages with full stack traces
  • Integration with Aspire dashboard for visibility
  • Configuration errors detected early

Usage Scenarios

Development

var dbMigrator = builder.AddDBMigrator("dbmigrator", database, "./Migrations")
    .WithSkipValidation()  // Faster startup in dev
    .WithDryRun();         // Test without changes

Production

var dbMigrator = builder.AddDBMigrator("dbmigrator", database, "./Migrations");
builder.AddDBMigratorLifecycleHook();
// Full validation and migration

Multiple Databases

var db1Migrator = builder.AddDBMigrator("migrator1", db1, "./Migrations/DB1");
var db2Migrator = builder.AddDBMigrator("migrator2", db2, "./Migrations/DB2");
builder.AddDBMigratorLifecycleHook();

Benefits

For Developers

? Automatic migrations - No manual migration steps
? Type-safe configuration - Fluent C# API
? Integrated logging - See migrations in Aspire dashboard
? Local development - Works with local SQL Server containers
? Dependency management - Apps wait for migrations

For Operations

? Consistent deployment - Same process everywhere
? Validation built-in - Prevents manual changes
? Dry run testing - Test before committing
? Comprehensive logging - Audit trail of changes
? Error handling - Fails fast on problems

Migration from CLI

Before (CLI)

dbmigrator upgrade -s server -d database -u user -p pass -f ./Migrations

After (Aspire)

builder.AddDBMigrator("dbmigrator", database, "./Migrations");
builder.AddDBMigratorLifecycleHook();

The migrations now run automatically as part of application startup!

Testing

Unit Tests

Tests cover:

  • Resource creation and configuration
  • Annotation application
  • Fluent API chaining
  • Dependency management

Integration Testing

Can be tested with Aspire.Hosting.Testing:

var appHost = await DistributedApplicationTestingBuilder
    .CreateAsync<Projects.TestAppHost>();
await using var app = await appHost.BuildAsync();
await app.StartAsync();
// Verify migrations ran successfully

Package Distribution

The integration can be published as a NuGet package:

  • Package ID: DBMigrator.Aspire.Hosting
  • Description: .NET Aspire integration for DBMigrator
  • Tags: aspire, dbmigrator, database, migration
  • Target Framework: .NET 9.0

Future Enhancements

Potential improvements:

  • Health check integration
  • Enhanced dashboard visualization
  • Rollback/downgrade support in Aspire
  • Parallel migration execution
  • Azure SQL authentication support
  • Migration history UI

Documentation

Comprehensive documentation created:

  • DBMigrator.Aspire.Hosting/README.md - User guide
  • DBMigrator.Aspire.Hosting/ARCHITECTURE.md - Technical details
  • Examples/DBMigrator.Aspire.Example/README.md - Example walkthrough
  • Main README.md updated with Aspire section

Compatibility

  • .NET Version: 9.0
  • .NET Aspire: 9.0 or later
  • SQL Server: Any version supported by DBMigrator
  • Existing DBMigrator: Fully compatible with existing migrations

Next Steps

To start using the integration:

  1. Install the package (once published):

    dotnet add package DBMigrator.Aspire.Hosting
  2. Update your AppHost:

    var dbMigrator = builder.AddDBMigrator("dbmigrator", database, "./Migrations");
    builder.AddDBMigratorLifecycleHook();
  3. Run your Aspire app:

    dotnet run
  4. See migrations in action:

    • Open Aspire dashboard
    • View DBMigrator logs
    • Verify migrations applied

Files Summary

Total files created: 17

Core Package (7 files)

  • Project and configuration files
  • Resource implementation
  • Extension methods
  • Documentation

Example Project (7 files)

  • Example AppHost
  • Sample migrations
  • Documentation

Test Project (2 files)

  • Test project
  • Unit tests

Updated Files (1)

  • Main README.md with Aspire integration section

Conclusion

The DBMigrator Aspire integration provides a seamless, developer-friendly way to handle database migrations in .NET Aspire applications. It maintains all the power and validation capabilities of DBMigrator while automating the execution as part of the application lifecycle.

The integration follows Aspire's patterns and conventions, making it feel like a natural extension of the platform. Developers can configure migrations using a fluent C# API, see results in the Aspire dashboard, and ensure their databases are always in the correct state before their applications start.