IDesignTimeDbContextFactory not always needed?

Viewed 2598

Previously i had to implement IDesignTimeDbContextFactory to get migrations running, e.g: PM > Add-Migration Initial PM > Update-Database

If not, the console threw an error and led me here: https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext#use-idesigntimedbcontextfactory.

So i did what it suggested and got migrations running. After that i have created new projects, and i didn't have to implement the IDesignTimeDbContextFactory. Migrations worked anyway. How is this possible? Same .NET Core version (2.0) on all of the projects.

Do we always need to create a IDesignTimeDbContextFactory, or is it just in certain situations?

Thanks!

2 Answers

As Dan Banan stated, if a DbContext has a default constructor, it won't need an IDesignTimeDbContextFactory at design time. However, if it needs to be configured from Startup, it will need a constructor which takes accepts DbContextOptions<T> and invokes the corresponding base constructor. However, this will create another issue. The DbContext's OnConfigure method will be called regardless of which constructor is used.

To account for these details, I've found the following pattern to be useful:

DbContext Configuration and Dependency Injection

serviceCollection
    .AddDbContext<MyDbContext>(
        options => options.UseSqlServer(configuration.GetConnectionString("MyDb"),
        ServiceLifetime.Transient
    );

MyDbContext.cs

public class MyDbContext : DbContext
{
    public SureshotDbContext()
    {
        // This allows for instantiation at design time.
    }

    public MyDbContext(DbContextOptions<MyDbContext> options) :
        base(options)
    {
        // This allows for configuration in real applications.
    }

    protected override void OnConfiguring(
        DbContextOptionsBuilder optionsBuilder
    )
    {
        if (optionsBuilder.IsConfigured)
        {
            return;
        }

        optionsBuilder.UseSqlServer(nameof(TDbContext));
    }
}
Related