EF Core: Add provider extension points for DBContext registration and database configuration.#21746
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a more flexible and extensible architecture for EF Core database provider registration by adding two new interfaces: IDbContextServiceRegistrar for registering provider-specific services (like distributed locking mechanisms) and IDatabaseConfigurator for configuring DbContext options (calling UseSqlite, UseSqlServer, etc.). This architectural change eliminates the need for the Umbraco.Cms.Persistence.EFCore project and removes hard dependencies on specific EF Core provider packages from the Infrastructure layer.
Changes:
- Added
IDbContextServiceRegistrarandIDatabaseConfiguratorinterfaces with aDbContextRegistrationcoordinator class to handle bidirectional service registration between DbContext types and provider-specific services - Moved database provider constants from
Umbraco.Cms.Infrastructure.Persistence.EFCore.ConstantstoUmbraco.Cms.Core.Constants - Removed
Umbraco.Cms.Persistence.EFCoreproject from the solution and removed EF Core provider package references from Infrastructure
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| umbraco.sln | Removed Umbraco.Cms.Persistence.EFCore project and build configurations |
| tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj | Removed reference to deleted Umbraco.Cms.Persistence.EFCore project |
| tests/Umbraco.Tests.Integration/Umbraco.Persistence.EFCore/DbContext/TestMigrationProviderSetup.cs | Updated to use Constants from Umbraco.Cms.Core |
| src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj | Removed direct dependencies on EF Core provider packages |
| src/Umbraco.Infrastructure/Persistence/EFCore/StringExtensions.cs | Added using directive for Core constants |
| src/Umbraco.Infrastructure/Persistence/EFCore/IDbContextServiceRegistrar.cs | New interface for provider-specific service registration |
| src/Umbraco.Infrastructure/Persistence/EFCore/IDatabaseConfigurator.cs | New interface for database provider configuration |
| src/Umbraco.Infrastructure/Persistence/EFCore/Extensions/UmbracoEFCoreServiceCollectionExtensions.cs | Replaced hard-coded provider switch with dynamic configurator lookup and integrated DbContextRegistration |
| src/Umbraco.Infrastructure/Persistence/EFCore/Extensions/DbContextRegistrationExtensions.cs | New extension methods for DbContextRegistration |
| src/Umbraco.Infrastructure/Persistence/EFCore/Extensions/DbContextExtensions.cs | Refactored method to expression-bodied member |
| src/Umbraco.Infrastructure/Persistence/EFCore/DbContextRegistration.cs | New coordinator class handling bidirectional registration between DbContext types and provider services |
| src/Umbraco.Infrastructure/Persistence/EFCore/Constants-ProviderNames.cs | Deleted (moved to Core) |
| src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj | Removed EF Core provider package references |
| src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj | Changed project reference from Persistence.EFCore to Infrastructure |
| src/Umbraco.Cms.Persistence.EFCore.Sqlite/SqliteMigrationProviderSetup.cs | Removed unused using statements |
| src/Umbraco.Cms.Persistence.EFCore.Sqlite/SqliteMigrationProvider.cs | Added using for Core constants |
| src/Umbraco.Cms.Persistence.EFCore.Sqlite/SqliteEFCoreDistributedLockingMechanism.cs | Changed visibility from internal to public and added using for Core constants |
| src/Umbraco.Cms.Persistence.EFCore.Sqlite/SqliteDbContextServiceRegistrar.cs | New registrar implementing IDbContextServiceRegistrar |
| src/Umbraco.Cms.Persistence.EFCore.Sqlite/SqliteDatabaseConfigurator.cs | New configurator implementing IDatabaseConfigurator |
| src/Umbraco.Cms.Persistence.EFCore.Sqlite/EFCoreSqliteComposer.cs | Updated to register configurator and service registrar |
| src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj | Changed project reference from Persistence.EFCore to Infrastructure |
| src/Umbraco.Cms.Persistence.EFCore.SqlServer/SqlServerMigrationProviderSetup.cs | Removed unused using statements |
| src/Umbraco.Cms.Persistence.EFCore.SqlServer/SqlServerMigrationProvider.cs | Added using for Core constants |
| src/Umbraco.Cms.Persistence.EFCore.SqlServer/SqlServerEFCoreDistributedLockingMechanism.cs | Changed visibility from internal to public |
| src/Umbraco.Cms.Persistence.EFCore.SqlServer/SqlServerDbContextServiceRegistrar.cs | New registrar implementing IDbContextServiceRegistrar |
| src/Umbraco.Cms.Persistence.EFCore.SqlServer/SqlServerDatabaseConfigurator.cs | New configurator implementing IDatabaseConfigurator |
| src/Umbraco.Cms.Persistence.EFCore.SqlServer/EFCoreSqlServerComposer.cs | Updated to register configurator and service registrar |
src/Umbraco.Infrastructure/Persistence/EFCore/DbContextRegistration.cs
Outdated
Show resolved
Hide resolved
…ation.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Looks a very well-designed solution to me @nikolajlauridsen, and resolves the issue you had around having to bring in details of database specific implementations into the Infrastructure project, allowing potential support for other providers in packages.
I had a few inline comments for you to consider, but nothing too significant.
There's something to figure out regarding the integration tests - I see failures with: "The provider Microsoft.Data.Sqlite is not supported. Ensure the appropriate EF Core provider package is installed".
Then just wanted to make an early comment about documentation:
- In time of course there will need to be public documentation about some of these registration concepts, including details of the two interfaces. That's not needed now, but maybe it's worth starting a document detailing what will need documenting so these things are captured.
- What you could do as part of this PR is updated the
Claude.mdfiles, so they reflect the changes in here. At the very least there are some changes to project structure worth documenting, and it would be worth adding reference toIDatabaseConfiguratorandIDbContextServiceRegistrartoo (and I'm sure Claude can help you write it's own documentation!).
src/Umbraco.Cms.Persistence.EFCore.Sqlite/SqliteDbContextServiceRegistrar.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Cms.Persistence.EFCore.Sqlite/SqliteDbContextServiceRegistrar.cs
Outdated
Show resolved
Hide resolved
...aco.Infrastructure/Persistence/EFCore/Extensions/UmbracoEFCoreServiceCollectionExtensions.cs
Show resolved
Hide resolved
Update documentation to reflect removal of Umbraco.Cms.Persistence.EFCore project and the new provider registration pattern. EF Core abstractions now live in Umbraco.Infrastructure/Persistence/EFCore/ and provider packages depend directly on Infrastructure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks Andy, great comments 🎉 I've fixed the tests, just forgot to update the registrations after moving everything around. I've also gotten Claude to update the MD files now. And I agree we sould document these new extension points at some point 😄 |
71b251c
into
v18/feature/ef-core-repositories
This PR adds two new interfaces:
IDbContextServiceRegistrarfor registering services for every registeredDbContextandIDatabaseConfiguratorfor configuringDbContexts(callingUseSqliteetc). This allows us to move the distributed locking mechanism out of Infrastructure and drop the reference toMicrosoft.EntityFrameworkCore.SqlServerandMicrosoft.EntityFrameworkCore.Sqlite, and also means there's no need forUmbraco.Cms.Persistence.EFCorecause everything that's not in infrastructure can be done from the respective packages.Testing
Ensure that tests pass and backoffice works as intended