At the current moment all default Startup.cs
flow executed on every db related operation like droping db, adding migration, updating db to migrations, etc.
I have heavy app specific code in Startup
which need to be invoked only if application run for real. So how could I detect that Startup
class run from migration or other database related dotnet
command.
Well, as it was already noticed in comment to a question there is a IDesignTimeDbContextFactory
interface which need to be implemented to resolve DbContext
at design time.
It could look somewhat like this:
public static class Programm{
...
public static IWebHost BuildWebHostDuringGen(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<StartupGen>() // <--- I'm just using different Startup child there where could be less complex code
.UseDefaultServiceProvider(options => options.ValidateScopes = false).Build();
}
}
public class DbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
public MyDbContex CreateDbContext(string[] args)
{
return Program.BuildWebHostDuringGen(args).Services.GetRequiredService<MyDbContext>();
}
}
However, due to some unclear reasons (I asked guys from Microsoft, but they don't explain this to me) dotnet
currently on every operation implicitly call Programm.BuildWebHost
even if it's private - that's the reason why standard flow executed each time for the question's author. Workaround for that - Rename Programm.BuildWebHost
to something else, like InitWebHost
There is an issue created for that, so maybe it will be resolved in 2.1 release on in future.
The documentation is still a bit unclear as to why this occurs. I've yet to find any concrete answer as to why it runs Startup.Configure
. In 2.0 it's recommend to move any migration/seeding code to Program.Main
. Here's an example by bricelam on Github.
public static IWebHost MigrateDatabase(this IWebHost webHost)
{
using (var scope = webHost.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var db = services.GetRequiredService<ApplicationDbContext>();
db.Database.Migrate();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while migrating the database.");
}
}
return webHost;
}
public static void Main(string[] args)
{
BuildWebHost(args)
.MigrateDatabase()
.Run();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With