efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Support setting implementation type for DbContextFactory

Open WolfspiritM opened this issue 4 years ago • 2 comments

Currently we're handling Migrations for two different data providers similar to how it is suggested here: https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/providers?tabs=dotnet-core-cli

And we use configuration to switch between the two implementations via:

services.AddDbContext<ApplicationDbContext, PostgresApplicationDbContext>(...);
services.AddDbContext<ApplicationDbContext, SqlApplicationDbContext>(...);

This works fine so far but with the new AddDbContextFactory this doesn't seem to be supported anymore. This doesn't work:

services.AddPooledDbContextFactory<ApplicationDbContext, PostgresApplicationDbContext>(...);
services.AddPooledDbContextFactory<ApplicationDbContext, SqlApplicationDbContext>(...);

and this doesn't work aswell (as the implementation is not

services.AddDbContextFactory<ApplicationDbContext, PostgresApplicationDbContext>(...);
services.AddDbContextFactory<ApplicationDbContext, SqlApplicationDbContext>(...);

As AddDbContext supports to specify the service type and also the implementation type I'd expect these methods to support that aswell in a way. I know that AddDbContextFactory already has a second type argument which is the factory so I guess that is the reason why the implementation was dropped?! I could create a factory for my db contexts but PooledDbContext doesn't support either the Implementation type nor a Factory type.

WolfspiritM avatar Feb 17 '21 11:02 WolfspiritM

Note for triage: we should consider adding this, but also be aware of the possible tooling impact: #14307

ajcvickers avatar Feb 22 '21 18:02 ajcvickers

Any update on this? I need this for a project I am working on. Or at least, what is the proper workaround? I've created my own factory like this:

public class ImplementationDbContextFactory<TContext, TImplementation> : IDbContextFactory<TContext>
    where TContext : DbContext
    where TImplementation : TContext
{
    private readonly IServiceProvider _serviceProvider;
    private readonly DbContextOptions<TImplementation> _options;
    private readonly Func<IServiceProvider, DbContextOptions<TImplementation>, TImplementation> _factory;

    public ImplementationDbContextFactory(
        IServiceProvider serviceProvider,
        DbContextOptions<TImplementation> options,
        IDbContextFactorySource<TImplementation> factorySource)
    {
        _serviceProvider = serviceProvider;
        _options = options;
        _factory = factorySource.Factory;
    }

    public TContext CreateDbContext()
    {
        return _factory(_serviceProvider, _options);
    }
}

But I am getting warnings saying that IDbContextFactorySource is an internal API.

FancyFurret avatar Apr 29 '24 19:04 FancyFurret