DEV Community

jacob
jacob

Posted on

Configure entity framework with dependency injection

Problem

You're following the configuration options pattern. To configure an entity framework context, you need to inject an IOptions container. But during ConfigureServices, the dependency injection container isn't ready.

Is this useful to me?

Should be relevant to at least asp core 2.2 and 3.x.

Solution

Entity framework lets you provide a context factory. The factory is defined during ConfigureServices, but it's only used after. Use the overload with a callback that includes an IServiceProvider. The IServiceProvider gives access to the DI container, so you can access any IOptions.

public void ConfigureServices(IServiceCollection services)
{
  services.Configure<DatabaseSettings>(o =>
  {
    o.Database = "some db";
    o.Username = "some user";
    o.Password = "some password";
  });

  services.AddDbContextPool<MyDbContext>((IServiceProvider sp, DbContextOptionsBuilder builder) =>
  {
    var dbsettings = sp.GetRequiredService<IOptions<DatabaseSettings>>();
    var env = sp.GetRequiredService<IWebHostEnvironment>();
    builder.UseNpgsql(dbsettings.Value.GetConnectionString());
    builder.EnableSensitiveDataLogging(env.IsDevelopment());
  });
}

public class DatabaseSettings
{
  public string Database { get; set; }
  public string Username { get; set; }
  public string Password { get; set; }
  public string GetConnectionString() => new NpgsqlConnectionStringBuilder
  {
    // ...
  }.ConnectionString;
}

For this to work, your context must have a single constructor. That constructor must accept a DbContextOptions object:

public class MyDbContext : DbContext
{
  // ...

  public MyDbContext(DbContextOptions options) : base(options) { }
}

You can override OnConfiguring if you like, the docs say:

If both are used, OnConfiguring is applied last and can overwrite options supplied to the constructor argument.

Can I use IConfigureOptions?

No.

Lots of things need to be configured inside ConfigureServices, but also need IOptions. Entity framework uses a factory callback pattern. Another pattern asp core uses is IConfigureOptions. Ef core 3.1 does not use the IConfigureOptions pattern.

Further reading

Top comments (0)