0

I am trying to write a generic service registration method, that can register a configurable EF Core DBContext.

I have an enum with the allowed database types, which I would like to be able to expand in the future to add cosmos, Postgres etc

public enum DatabaseConnectionTypes
{
  InMemory,
  SqlServer
}

I am reading the database type and connection string from appsettings

public static IServiceCollection AddDatabaseContext<T>(this IServiceCollection services, IConfiguration configuration) where T : DBContext
{
  var connectionStringName = configuration.GetValue<string>(StringConstants.DatabaseConnectionStringName);
  var connectionString = configuration.GetConnectionString(connectionStringName);
  var connectionType = configuration.GetValue<string>(StringConstants.DatabaseConnectionType);
  services.AddEFContext<T>(connectionString, (DatabaseConnectionTypes)Enum.Parse(typeof(DatabaseConnectionTypes), connectionType));
  return services;
}

here is where i just can't think of an elegant way to manage this other than a switch

private static IServiceCollection AddEFContext<T>(this IServiceCollection services, string connectionString, DatabaseConnectionTypes connectionTypes) where T : DbContext
{
  // I don't want a switch here
  //
  switch (connectionTypes)
  {
    case DatabaseConnectionTypes.SqlServer:
      services.AddDbContext<T>(x => x.UseSqlServer(connectionString, c => c.MigrationsAssembly(typeof(T).Assembly.FullName)));
      break;
    default:
      services.AddDbContext<T>(x => x.UseInMemoryDatabase(connectionString));
      break;
  }
  using var scope = services.BuildServiceProvider().CreateScope();
  var dbContext = scope.ServiceProvider.GetRequiredService<T>();
  return services;
}
  • Reflection can instantiate a type from a fully qualified type name. That's the only way I can think of to avoid the `switch`. See https://stackoverflow.com/questions/2247598 – Robert Harvey Sep 21 '21 at 23:21
  • You won't be using an `enum` if you do this, however. – Robert Harvey Sep 21 '21 at 23:23
  • 2
    You could follow the strategy pattern. Pass in a lambda or IEntityFrameworkConfigurator to your method. – mason Sep 21 '21 at 23:24

0 Answers0