using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Polly; using Polly.Retry; using System; using System.Data.SqlClient; namespace Microsoft.AspNetCore.Hosting { public static class IWebHostExtensions { public static IWebHost MigrateDbContext(this IWebHost webHost, Action seeder) where TContext : DbContext { using (var scope = webHost.Services.CreateScope()) { var services = scope.ServiceProvider; var logger = services.GetRequiredService>(); var context = services.GetService(); try { logger.LogInformation($"Migrating database associated with context {typeof(TContext).Name}"); var retry = Policy.Handle() .WaitAndRetry(new TimeSpan[] { TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), }); retry.Execute(() => { //if the sql server container is not created on run docker compose this //migration can't fail for network related exception. The retry options for DbContext only //apply to transient exceptions. context.Database .Migrate(); seeder(context, services); }); logger.LogInformation($"Migrated database associated with context {typeof(TContext).Name}"); } catch (Exception ex) { logger.LogError(ex, $"An error occurred while migrating the database used on context {typeof(TContext).Name}"); } } return webHost; } } }