`dotnet-ef migrations add` starts entire application when CreateHostBuilder method is not present

See original GitHub issue

TLTR When public static IHostBuilder CreateHostBuilder(string[] args) method is removed from Program.cs in a web api template project with dependencies on EF 6, generating migration with dotnet ef CLI tool starts the entire application instead of generating migration. In EF 5 this behaviour was not present.


Hello, I’ve encountered strange behaviour of the dotnet ef CLI tool after updating my application to EF 6. Program.cs in our microservices looks like this:

public class Program
{
    public static Task Main(string[] args) => WebHostHelper.BuildAndRunWebHostAsync<Startup>(args, validateDiConfigurationInDebug: true);
}

As you can see it lacks CreateHostBuilder(string[] args) because it wouldn’t be productive to add this method in all microservices. Instead, we provide a helper method as above. Also, what is important, our application is implementing IDesignTimeDbContextFactory in order to control creating of DbContext when migrations are being added (find simple reproduction here: https://github.com/marekott/dotnet-ef-add-migration-bug-reproduction). When application had dependency on EF 5 dotnet-ef migrations add Initial -v command produced valid migration (logs below). After updating to EF 6 the same command starts the entire application (logs below) that needs to be killed in order to finish producing migration (which in the end is a valid one). Adding CreateHostBuilder(string[] args) resolves this issue, application is not started and migration is generated. However, adding this method especially that it is not used and wasn’t needed for 3 years seem as a lazy solution.

Taking everything into consideration what is a reason for this strange behaviour? It seems like a bug, especially that it has worked previously.

Logs for EF 5

PS C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi> dotnet-ef migrations add Initial
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PS C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi> dotnet-ef migrations add Initial -v
Using project 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj'.
Using startup project 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj'.
Writing 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\obj\SampleWebApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\marek.ott\AppData\Local\Temp\tmp277A.tmp /verbosity:quiet /nologo C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj
Writing 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\obj\SampleWebApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\marek.ott\AppData\Local\Temp\tmp2A4A.tmp /verbosity:quiet /nologo C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj
Build started...
dotnet build C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj /verbosity:quiet /nologo

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.28
Build succeeded.
dotnet exec --depsfile C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.deps.json --additionalprobingpath C:\Users\marek.ott\.nuget\packages --runtimeconfig C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.runtimeconfig.json C:\Users\marek.ott\.dotnet\tools\.store\dotnet-ef\6.0.5\dotnet-ef\6.0.5\tools\netcoreapp3.1\any\tools\netcoreapp2.0\any\ef.dll migrations add Initial --assembly C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.dll --project C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj --startup-assembly C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.dll --startup-project C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj --project-dir C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\ --root-namespace SampleWebApi --language C# --framework net6.0 --working-dir C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi --verbose
Using assembly 'SampleWebApi'.
Using startup assembly 'SampleWebApi'.
Using application base 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0'.
Using working directory 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi'.
Using root namespace 'SampleWebApi'.
Using project directory 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'PostgresDbContextMigrationsFactory'.
Found DbContext 'SampleWebApiContext'.
Finding application service provider in assembly 'SampleWebApi'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Using DbContext factory 'PostgresDbContextMigrationsFactory'.
Using context 'SampleWebApiContext'.
Finding design-time services for provider 'Npgsql.EntityFrameworkCore.PostgreSQL'...
Using design-time services from provider 'Npgsql.EntityFrameworkCore.PostgreSQL'.
Finding design-time services referenced by assembly 'SampleWebApi'...
Finding design-time services referenced by assembly 'SampleWebApi'...
No referenced design-time services were found.
Finding IDesignTimeServices implementations in assembly 'SampleWebApi'...
No design-time services were found.
DetectChanges starting for 'SampleWebApiContext'.
DetectChanges completed for 'SampleWebApiContext'.
Writing migration to 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\Migrations\20220526065812_Initial.cs'.
Writing model snapshot to 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\Migrations\SampleWebApiContextModelSnapshot.cs'.
'SampleWebApiContext' disposed.
Done. To undo this action, use 'ef migrations remove'

Logs for EF 6

dotnet-ef migrations add Initial -v
Using project 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj'.
Using startup project 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj'.
Writing 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\obj\SampleWebApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\marek.ott\AppData\Local\Temp\tmp423C.tmp /verbosity:quiet /nologo C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj
Writing 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\obj\SampleWebApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\marek.ott\AppData\Local\Temp\tmp4460.tmp /verbosity:quiet /nologo C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj
Build started...
dotnet build C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj /verbosity:quiet /nologo

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.60
Build succeeded.
dotnet exec --depsfile C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.deps.json --additionalprobingpath C:\Users\marek.ott\.nuget\packages --runtimeconfig C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.runtimeconfig.json C:\Users\marek.ott\.dotnet\tools\.store\dotnet-ef\6.0.5\dotnet-ef\6.0.5\tools\netcoreapp3.1\any\tools\netcoreapp2.0\any\ef.dll migrations add Initial --assembly C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.dll --project C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj --startup-assembly C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0\SampleWebApi.dll --startup-project C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\SampleWebApi.csproj --project-dir C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\ --root-namespace SampleWebApi --language C# --framework net6.0 --working-dir C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi --verbose
Using assembly 'SampleWebApi'.
Using startup assembly 'SampleWebApi'.
Using application base 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\bin\Debug\net6.0'.
Using working directory 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi'.
Using root namespace 'SampleWebApi'.
Using project directory 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'PostgresDbContextMigrationsFactory'.
Found DbContext 'SampleWebApiContext'.
Finding application service provider in assembly 'SampleWebApi'...
Finding Microsoft.Extensions.Hosting service provider...
Using environment 'Development'.
Hosting environment: Development
Content root path: C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi
Now listening on: http://localhost:5000
Now listening on: https://localhost:5001
Application started. Press Ctrl+C to shut down.
Application is shutting down...
PS C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi> System.InvalidOperationException: The entry point exited without ever building an IHost.
   at Microsoft.Extensions.Hosting.HostFactoryResolver.HostingListener.CreateHost()
   at Microsoft.Extensions.Hosting.HostFactoryResolver.<>c__DisplayClass10_0.<ResolveHostFactory>b__0(String[] args)
   at Microsoft.Extensions.Hosting.HostFactoryResolver.<>c__DisplayClass13_0.<ResolveServiceProviderFactory>b__3(String[] args)
   at Microsoft.EntityFrameworkCore.Design.Internal.AppServiceProviderFactory.CreateFromHosting(String[] args)
An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the application service provider. Error: The entry point exited without ever building an IHost.
No application service provider was found.
Finding DbContext classes in the project...
Using DbContext factory 'PostgresDbContextMigrationsFactory'.
Using context 'SampleWebApiContext'.
Finding design-time services referenced by assembly 'SampleWebApi'...
Finding design-time services referenced by assembly 'SampleWebApi'...
No referenced design-time services were found.
Finding design-time services for provider 'Npgsql.EntityFrameworkCore.PostgreSQL'...
Using design-time services from provider 'Npgsql.EntityFrameworkCore.PostgreSQL'.
Finding IDesignTimeServices implementations in assembly 'SampleWebApi'...
No design-time services were found.
DetectChanges starting for 'SampleWebApiContext'.
DetectChanges completed for 'SampleWebApiContext'.
Writing migration to 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\Migrations\20220526070035_Initial.cs'.
Writing model snapshot to 'C:\Users\marek.ott\Desktop\demo\SampleWebApi\SampleWebApi\Migrations\SampleWebApiContextModelSnapshot.cs'.
'SampleWebApiContext' disposed.
Done. To undo this action, use 'ef migrations remove'

My dotnet ef version is:

Entity Framework Core .NET Command-line Tools
6.0.5

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:3
  • Comments:14 (8 by maintainers)

github_iconTop GitHub Comments

4reactions
KrzysztofBranickicommented, Jun 3, 2022

@davidfowl During application startup lot of things can be performed: microservice can send some message to the message bus indicating that it is started, it may register itself in Consul, some data seeding can take place. None of those is expected behavior when you are using EF tooling to generate new migration. Also application may require some mandatory configuration to be provided via env variables or Kubernetes mounted file (e.g. availability zone) without which it will throw, obviously you wouldn’t want to provide this configuration just to generate EF migration. Long story short it is not expected behavior that adding database migration will start your application, but if you don’t want to change existing behavior then at least add ability to directly specify in CLI IDesignTimeDbContextFactory (as @plachor suggested) which we have implemented exactly for the reason of constructingDbContext for the EF CLI tooling purpose.

3reactions
plachorcommented, May 27, 2022

That: https://github.com/dotnet/efcore/issues/27322#issue-1119743287 would be best option for this case I believe. Since in docs you mentioned that:

… The generic hosting model is an alternative model that is supported indefinitely. The generic host underpins the new hosting model and is still the primary way to host worker-based applications.

Or allow to specify IDesignTimeDbContextFactory type explicitly in dotnet ef command instead of context.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does application start with dotnet ef migrations add?
EF will look for a CreateHostBuilder method in Program . If it finds it, it won't call Main , and basically skip the...
Read more >
Applying Migrations - EF Core
Strategies for applying schema migrations to production and development databases using Entity Framework Core.
Read more >
Supporting EF Core migrations with WebApplicationBuilder
In this post I describe how HostBuilder had to be updated to support the EF Core tools after the introduction of WebApplication and ......
Read more >
Entity Framework Core Migrations
The migrations feature in Entity Framework Core enables you to make changes to your model and then propagate those changes to your database ......
Read more >
How to Solve the Command or File Was Not Found EF ...
In this article, we are going to learn how to solve the Command or File Was Not Found EF Core migration error.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found