Description
There have been some changes made in 2.0 to the way EF Core discovers and creates your DbContext
at design-time.
Please provide any feedback in the discussion thread at dotnet/efcore#9033.
Summary by @bricelam:
New way of getting application services
The recommended pattern for ASP.NET Core web applications has been updated for 2.0 in a way that broke the design-time logic EF Core used in 1.x. Previously at design-time, EF Core would try to invoke Startup.ConfigureServices
directly in order to access the application's service provider. In ASP.NET Core 2.0, Configuration is initialized outside of the Startup
class. Applications using EF Core typically access their connection string from Configuration, so Startup
by itself is no longer sufficient. If you upgrade an ASP.NET Core 1.x application, you may receive the following error when using the EF Core tools.
No parameterless constructor was found on 'ApplicationContext'. Either add a parameterless constructor to 'ApplicationContext' or add an implementation of 'IDesignTimeDbContextFactory<ApplicationContext>' in the same assembly as 'ApplicationContext'
A new design-time hook has been added in ASP.NET Core 2.0. The static Program.BuildWebHost
method enables EF Core to access the application's service provider at design time. If you are upgrading an ASP.NET Core 1.x application, you will need to update you Program
class to resemble the following.
public class Program
{
public static void Main(string[] args)
{
var host = BuildWebHost(args);
host.Run();
}
// Tools will use this to get application services
public static IWebHost BuildWebHost(string[] args) =>
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}
IDbContextFactory renamed
In order to support diverse application patterns and give users more control over how their DbContext
is used at design time, we have, in the past, provided the IDbContextFactory<TContext>
interface. At design-time, the EF Core tools will discover implementations of this interface in your project and use it to create DbContext
objects.
This interface had a very general name which mislead some users to try re-using it for other DbContext
-creating scenarios. They were caught off guard when the EF Tools then tried to use their implementation at design-time and caused commands like Update-Database
or dotnet ef database update
to fail.
In order to communicate the strong design-time semantics of this interface, we have renamed it to IDesignTimeDbContextFactory<TContext>
.
For the 2.0 release the IDbContextFactory<TContext>
still exists but is marked as obsolete.
DbContextFactoryOptions removed
Because of the ASP.NET Core 2.0 changes described above, we found that DbContextFactoryOptions
was no longer needed on the new IDesignTimeDbContextFactory<TContext>
interface. Here are the alternatives you should be using instead.
DbContextFactoryOptions | Alternative |
---|---|
ApplicationBasePath | AppContext.BaseDirectory |
ContentRootPath | Directory.GetCurrentDirectory() |
EnvironmentName | Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") |