Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 10, 2025

Description

New hosting integration package Aspire.Hosting.EntityFrameworkCore that provides EF Core migration management commands for Aspire AppHost projects.

Key Features

  • AddEFMigrations extension methods - Add migration resources to project resources with optional DbContext type specification. Supports both generic AddEFMigrations<TContext>() and string-based AddEFMigrations(name, contextTypeName) overloads.
  • EFMigrationResourceBuilder - Custom builder class with fluent configuration methods: RunDatabaseUpdateOnStart(), PublishAsMigrationScript(), PublishAsMigrationBundle(), WithMigrationOutputDirectory(), WithMigrationNamespace(), WithMigrationsProject()
  • 6 resource commands on project resource - Update Database, Drop Database, Reset Database, Add Migration (with interactive prompt), Remove Migration, Get Database Status - commands are added to the original project resource with context name suffix to avoid confusion when multiple DbContexts are registered
  • WaitFor support with health checks - EFMigrationResource implements IResourceWithWaitSupport. When RunDatabaseUpdateOnStart() is called, a health check is registered that reports healthy only when migrations complete. Migrations wait for the project resource to be healthy before executing.
  • Separate migration project support - Use WithMigrationsProject() when migrations are in a different project than the startup project. Both startup and target assemblies are loaded in the same AssemblyLoadContext.
  • Reflection-based EF Core executor with assembly isolation - Uses collectible AssemblyLoadContext to load and execute EF Core operations, with proper unloading after each operation. Uses MSBuild for property resolution with configuration/runtime heuristics.
  • Interactive migration naming - Uses IInteractionService.PromptInputAsync for Add Migration command with recompilation notification via PromptNotificationAsync. Remove Migration also shows recompilation notification.
  • Database status display - Uses IInteractionService.PromptMessageBoxAsync to show current migration status
  • Event-driven startup and publishing - EFMigrationEventSubscriber handles AfterResourcesCreatedEvent for startup migrations (after project resource is healthy) and BeforePublishEvent for generating migration scripts/bundles during publish

Checklist

  • Create new Aspire.Hosting.EntityFrameworkCore project structure
  • Create EFMigrationResource with IResourceWithWaitSupport
  • Create extension methods and EFMigrationResourceBuilder
  • Implement resource commands (on project resource with context name suffix)
  • Implement RunDatabaseUpdateOnStart with event subscriber (waits for project resource to be healthy)
  • Create EFCoreOperationExecutor using collectible AssemblyLoadContext
  • Integrate with resource health checks
  • Add migration configuration options (output directory, namespace, migrations project)
  • Integrate with publish pipeline for script/bundle generation
  • Use MSBuild with configuration/runtime heuristics for property resolution
  • All 50 tests pass
Original prompt

Create a new hosting integration that provides EF migration management commands. Start by creating a detailed step-by-step checklist as an .md file that should be updated as you finish tasks. Add tests for all the new functionality, including tests that use other features that could interact with this, like explicit start and wait for.

Package name: Aspire.Hosting.EFCoreCommands
Assembly name: Aspire.Hosting.EFCoreCommands

High-level feature outline

  • Support for producing migration scripts and/or migration bundles as part of publishing the AppHost, e.g. .PublishAsMigrationScript()
  • Support for running migrations on AppHost start and having other resources wait on the migrations to complete, e.g.:
    var api = builder.AddProject<Api>("api");
    var apiMigrations = api.AddEFMigrations("api-migrations").RunDatabaseUpdateOnStart();
  • Adds resource commands to resources that AddEfMigrations was called on:
    • "Update database": Runs the equivalent of ef database update command on the resource
    • "Drop database": Runs the equivalent of ef database drop command on the resource
    • "Reset database": Runs equivalent of ef database drop followed by dotnet ef database update on the resource
    • "Add migration...": Prompts for a migration name (and some options from dotnet ef migrations add) before running the equivalent of dotnet ef migrations add <NAME> on the resource. Add some notification to indicate that in order to apply the new migration the target project needs to be recompiled.
    • "Remove migration": Runs the equivalent of ef migrations remove on the resource to remove the last migration
    • "Get database status": Shows the current migration of the database or whether it hasn't been created. Whether the current migration is also the latest and whether there are any pending model changes.
  • AddEFMigrations should allow a context type to be specified. Multiple calls on the same resource with different context types are allowed and will add commands for each context used. Using the same context type results in an exception.
  • The implementation will check that the target references Microsoft.EntityFrameworkcore.Design and show an error message if it doesn't. Then it will use reflection to invoke commands on it with appropriate arguments, see https://github.com/dotnet/efcore/blob/main/src/ef/ReflectionOperationExecutor.cs
  • IOperationReporter should be used to capture the output of the operations

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits December 10, 2025 23:29
…anagement

- Create EFMigrationResource with IResourceWithWaitSupport
- Add AddEFMigrations extension methods for project resources
- Implement 6 resource commands: Update, Drop, Reset, Add, Remove, Status
- Add RunDatabaseUpdateOnStart and PublishAs* configuration methods
- Add EFCoreOperationExecutor for command execution
- Create comprehensive test suite with 36 passing tests
- Add detailed implementation checklist documentation

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI changed the title [WIP] Add hosting integration for EF migration management commands Add Aspire.Hosting.EFCoreCommands hosting integration for EF Core migration management Dec 10, 2025
Copilot AI requested a review from AndriySvyryd December 10, 2025 23:34
Copy link
Member

@AndriySvyryd AndriySvyryd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Continue implementation according to the checklist

- Reorganize README.md with Prerequisites section first, add PublishAsMigrationBundle example
- Move "Running migrations on startup" to separate subsection after Resource Commands
- Update prerequisites to recommend manual project file reference for Microsoft.EntityFrameworkCore.Design
- Add TODO comment for documentation link update
- Add remarks about multiple calls with different context types in extension methods
- Fix error message format for duplicate context registration
- Update implementation checklist with IDistributedApplicationEventingSubscriber note
- Add EFCoreCommands demo to SqlServerEndToEnd playground

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 11, 2025

@copilot Continue implementation according to the checklist

All review comments have been addressed in 5c8b132. Added EFCoreCommands demo to SqlServerEndToEnd playground and addressed all documentation feedback.

Copilot AI and others added 2 commits December 11, 2025 00:41
… dialog

- Create EFMigrationEventSubscriber using IDistributedApplicationEventingSubscriber
- Implement resource state transitions (Pending → Running → Finished/FailedToStart)
- Add IInteractionService.PromptInputAsync for migration name prompt
- Support custom migration name parameter in AddMigrationAsync
- Update implementation checklist with links and completion status
- Add test for event subscriber registration
- All 37 tests pass

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
- Update code example to use GetService instead of GetRequiredService
- Add fallback logic example matching actual implementation

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
- Create IEFMigrationResourceBuilder interface that stores ContextTypeName
- Create EFMigrationResourceBuilder implementation wrapping inner builder
- Update AddEFMigrations to return IEFMigrationResourceBuilder
- Add string overload AddEFMigrations(name, contextTypeName) for runtime discovery
- Add ContextTypeName property to EFMigrationResource
- Add recompilation notification after migration is added (via logs)
- Add 5 new tests for string context type overload
- All 42 tests pass

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
- Rename method WithMigrationProject to WithMigrationsProject
- Rename property MigrationProject to MigrationsProject in EFMigrationsOptions
- Update all references in extensions, event subscriber, README, and tests
- All 50 tests pass

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
The EFMigrationEventSubscriber now waits for the project resource
(the one on which AddEFMigrations was called) to be healthy before
attempting to apply migrations. This ensures the database connection
is available when migrations run.

- Use resourceNotificationService.WaitForResourceHealthyAsync before ApplyMigrationsAsync
- Log message indicating waiting for project resource to be healthy
- All 50 tests pass

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
else if (executionContext.IsPublishMode)
{
// In publish mode, generate migration scripts/bundles
eventing.Subscribe<BeforePublishEvent>(OnBeforePublishAsync);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot This should happen in a step not in an event.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidfowl I think copilot gave up on this PR

@github-actions
Copy link
Contributor

github-actions bot commented Dec 12, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 13481

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 13481"

@AndriySvyryd
Copy link
Member

This is how it looks right now
Screenshot 2025-12-12 170109

@AndriySvyryd
Copy link
Member

This is the database status dialog:
image


```csharp
var startup = builder.AddProject<Projects.Api>("api");
var dataProject = builder.AddProject<Projects.Data>("data");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidfowl How can I mark a project resource as "non-runnable"?

@AndriySvyryd AndriySvyryd marked this pull request as ready for review December 16, 2025 05:21
Copilot AI review requested due to automatic review settings December 16, 2025 05:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new hosting integration package Aspire.Hosting.EntityFrameworkCore that provides comprehensive EF Core migration management for Aspire AppHost projects.

Key additions:

  • Extension methods (AddEFMigrations<TContext>() with multiple overloads) to attach migration management to project resources
  • 6 dashboard resource commands (Update/Drop/Reset Database, Add/Remove Migration, Get Status) with interactive prompts
  • Reflection-based executor using collectible AssemblyLoadContext for EF Core operations
  • WaitFor support with health checks for migration dependencies
  • Event-driven startup migrations and publish pipeline integration
  • 50 comprehensive unit tests covering all functionality

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Aspire.Hosting.EntityFrameworkCore/Aspire.Hosting.EntityFrameworkCore.csproj New project file multi-targeting net8.0/9.0/10.0 with package validation disabled
src/Aspire.Hosting.EntityFrameworkCore/README.md Hosting integration documentation following standard structure with usage examples
src/Aspire.Hosting.EntityFrameworkCore/EFMigrationResource.cs Resource class implementing IResourceWithWaitSupport with configuration properties
src/Aspire.Hosting.EntityFrameworkCore/EFMigrationResourceBuilder.cs Custom builder with fluent configuration methods (RunDatabaseUpdateOnStart, Publish*, etc.)
src/Aspire.Hosting.EntityFrameworkCore/EFResourceBuilderExtensions.cs Extension methods for AddEFMigrations with 4 overloads and command registration
src/Aspire.Hosting.EntityFrameworkCore/EFMigrationHealthCheck.cs Health check implementation for migration state monitoring
src/Aspire.Hosting.EntityFrameworkCore/EFMigrationEventSubscriber.cs Event subscriber handling startup migrations via BeforeResourceStartedEvent
src/Aspire.Hosting.EntityFrameworkCore/EFCoreOperationExecutor.cs Reflection-based EF operation executor using AssemblyLoadContext isolation
tests/Aspire.Hosting.EntityFrameworkCore.Tests/*.cs Comprehensive test suite (50 tests) covering resource creation, configuration, commands, and WaitFor
playground/SqlServerEndToEnd/* Example integration showing AddEFMigrations usage with WaitFor dependencies
Aspire.slnx Solution file updated with new projects

AndriySvyryd and others added 3 commits December 16, 2025 10:33
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants