Allow End User to Switch Entity Framework Provider at Run Time

Note that I configured EF using the .NET Core web application:

services.AddDbContext<ApplicationDbContext>(options => 
    options.UseSqlServer(...));

I can also download the SQLite support package:

services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite(...));

How can we allow the user to "choose" a provider when installing the application? I mean - for example, in WordPress you can choose from a drop-down list.

Is this possible in .NET Core? The only way I see it is to restart the application only ...

+4
source share
2 answers

Here is an example of how you can implement DbContextFactoryor DbContextProxy<T>, which will create the right provider and return it.

public interface IDbContextFactory
{
    ApplicationContext Create();
}

public class DbContextFactory() : IDbContextFactory, IDisposable
{
    private ApplicationContext context;
    private bool disposing;

    public DbContextFactory()
    {
    }

    public ApplicationContext Create() 
    {
        if(this.context==null) 
        {
            // Get this value from some configuration
            string providerType = ...;
            // and the connection string for the database
            string connectionString = ...;

            var dbContextBuilder = new DbContextOptionsBuilder();
            if(providerType == "MSSQL") 
            {
                dbContextBuilder.UseSqlServer(connectionString);
            }
            else if(providerType == "Sqlite")
            {
                dbContextBuilder.UseSqlite(connectionString);
            }
            else 
            {
                throw new InvalidOperationException("Invalid providerType");
            }

            this.context = new ApplicationContext(dbContextBuilder);
        }

        return this.context;
    }

    public void Dispose(){
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing){
        if (disposing){
            disposing?.Dispose();
        }
    }
}

, , , , factory , DbContext , , .

, factory , :

services.AddScopedd<IDbContextFactory, DbContextFactory>();

/ IDbContextProxy<T>, DbContextOptionsBuilder .

IDbContextBuilder, .

public class SqlServerDbContextBuilder IDbContextBuilder
{
    public bool CanHandle(string providerType) => providerType == "SqlServer";

    public T CreateDbContext<T>(connectionString)
    {
        T context = ... // Create the context here

        return context;
    }
}

if/else switch,

// Inject "IEnumerable<IDbContextBuilder> builders" via constructor
var providerType = "SqlServer";
var builder = builders.Where(builder => builder.CanHandle(providerType)).First();
var context = builder.CreateDbContext<ApplicationContext>(connectionString);

, XxxDbContextBuilder.

, .

+2
0

Source: https://habr.com/ru/post/1661250/


All Articles