Constructor injection into IDesignTimeDbContextFactory

entity-framework entity-framework-core

Question

I'm attempting to use migrations EFCore2.0 in a .NET standard 2.0 class library, and so far I have something like

public class SomeContextFactory : IDesignTimeDbContextFactory<SomeContext>
{
    private Configuration _configuration;

    public SomeContextFactory(Configuration configuration)
    {
        _configuration = configuration;
    }

    public SomeContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<SomeContext>();

        optionsBuilder.UseSqlServer(_configuration.ConnectionString);

        return new SomeContext(optionsBuilder.Options);
    }
}

public class SomeContext : DbContext
{
    public DbSet<SomeDbModel> Some { get; set; }

    public SomeContext(DbContextOptions<SomeContext> options) : base(options)
    {
    }
}

The point is that the connection string is different depending on the environment (dev,test,prod), and migrations should be performed on the database specified by the Configuration.

How do instruct migrations to inject Configuration into SomeContextFactory?

1
3
10/5/2017 1:43:11 PM

Accepted Answer

By design, the IDesignTimeDbContextFactory isn't support to work with DI. One way to achieve this would be:

public class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
  public AppDbContext CreateDbContext(params string[] args)
  {
    var options = new DbContextOptionsBuilder<AppDbContext>();
    var config = GetAppConfiguration();
    options.UseSqlServer(config.GetConnectionString("DesignTimeAppDbConnection"));

    return new AppDbContext(options.Options);
  }

  IConfiguration GetAppConfiguration()
  {
    var environmentName =
              Environment.GetEnvironmentVariable(
                  "ASPNETCORE_ENVIRONMENT");

    var dir = Directory.GetParent(AppContext.BaseDirectory);      

    if(EnvironmentName.Development.Equals(environmentName, 
        StringComparison.OrdinalIgnoreCase))
    {                  
      var depth = 0;
      do
        dir = dir.Parent;
      while (++depth < 5 && dir.Name != "bin");
      dir = dir.Parent;
    }

    var path = dir.FullName;

    var builder = new ConfigurationBuilder()
            .SetBasePath(path)
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{environmentName}.json", true)
            .AddEnvironmentVariables();

    return builder.Build();
  }
}
3
5/31/2019 5:53:06 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow