Entityframework.docs: IDesignTimeDbContextFactory with dependency injection?

Created on 29 May 2019  Â·  5Comments  Â·  Source: dotnet/EntityFramework.Docs

When trying to create a DI-dependent implementation of IDesignTimeDbContextFactory, I get the following error upong trying to add migrations:

PM> add-migration InitialCreate -context AppDbContext
System.MissingMethodException: No parameterless constructor defined for this object.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContextFromFactory(Type factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_1.b__9()
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func1 factory) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_01.b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
No parameterless constructor defined for this object.
PM>


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Most helpful comment

Think of IDesignTimeDbContextFactory.CreateDbContext() like Program.Main() but for tools. It's the entry point. You'll need to build your service container before you can use DI.

All 5 comments

Think of IDesignTimeDbContextFactory.CreateDbContext() like Program.Main() but for tools. It's the entry point. You'll need to build your service container before you can use DI.

Your IDesignTimeDbContextFactory implementation needs a parameterless constructor. There are no services to inject yet.

Thank you @bricelam. Here's my implementation, for future reference. I believe once deployed I'm gonna need to work on it again, but it works now. Would have been nice if there was a better way to access the configuration off DI.

```c#
public class AppDbContextFactory : IDesignTimeDbContextFactory
{
public AppDbContext CreateDbContext(params string[] args)
{
var options = new DbContextOptionsBuilder();
var config = GetAppConfiguration();
options.UseSqlServer(config.GetConnectionString("DesignTimeAppDbConnection"));

return new AppDbContext(options.Options);

}

IConfiguration GetAppConfiguration()
{
var environmentName =
Environment.GetEnvironmentVariable(
"ASPNETCORE_ENVIRONMENT");

var dir = Directory.GetParent(AppContext.BaseDirectory);    
do
  dir = dir.Parent;
while (dir.Name != "bin");
dir = dir.Parent;
var path = dir.FullName;

var builder = new ConfigurationBuilder()
        .SetBasePath(path)
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{environmentName}.json", true)
        .AddEnvironmentVariables();

return builder.Build();

}
}
```

Would using the Program. CreateHostBuilder() pattern work better for you?

I'll check out your suggestion, but I realize that my real problem is this, which is happening at runtime.

Thank you @bricelam.

Was this page helpful?
0 / 5 - 0 ratings