A couple days ago I had to fix a EF Core issue experienced to one of my readers when he was working on the EF Core Migrations (Chapter 4 of ASP.NET Core 2 and Angular 5 book). This was the error, as reported on GitHub:
An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider.
Unable to create an object of type 'ApplicationDbContext'. Add an implementation of 'IDesignTimeDbContextFactory' to
the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
The issue
After some research through the official docs and similar issues I've seen that it was mostly due to the fact that they changed the behaviour of how the BuildWebHost method - which is invoked in the Program.cs file to obtain the application services - works: now it invokes the Configure method in the Startup.cs file, which could lead to unexpected problems if that method contains some database initialization code. The major issue there is that such "problems" will most likely raise misleading exceptions whenever the seeding code runs before the first dotnet ef migrations add / dotnet ef database update command execution - when the database doesn't yet exist.
The fix
Luckily enough, fixing that is just as easy as following the official EF Core 1.x to 2.x migration guide:
- Remove all the DB initialization code from the Startup.cs file's Configure() method.
- Put it into the Program.cs file's Main() method, in the following way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public static void Main(string[] args) { // REPLACE THIS: // BuildWebHost(args).Run(); // WITH THIS: var host = BuildWebHost(args); using (var scope = host.Services.CreateScope()) { // Retrieve your DbContext isntance here var dbContext = scope.ServiceProvider.GetService<ApplicationDbContext>(); // place your DB seeding code here DbSeeder.Seed(dbContext); } host.Run(); // ref.: https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/ } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); |
That's about it!