'Unable to create an object of type 'DbContext'

When I try to run

dotnet ef migration add Init

I get error

Unable to create an object of type 'IdentityContext'.

I know what caused the problem. I wanted to learn using message bus and added it to my project, so I run for some course and implemented it. Ofc bus working perfectly. But the problem is that I can no longer migrate via EF.

My Startup.cs before was.

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Now it looks like this.

public static void Main(string[] args)
{
  ServiceHost.Create<Startup>(args)
    .UseRabbitMq()
    .Build()
    .Run();
}

And ServiceHost class

public void Run() => _webHost.Run();

public static HostBuilder Create<TStartup>(string[] args) where TStartup : class
{
  Console.Title = typeof(TStartup).Namespace;
  var config = new ConfigurationBuilder()
    .AddEnvironmentVariables()
    .AddCommandLine(args)
    .Build();
  var webHostBuilder = WebHost.CreateDefaultBuilder()
    .UseConfiguration(config)
    .UseStartup<TStartup>();

  return new HostBuilder(webHostBuilder.Build());
}

So anyone would give advice why migration stopped to work? For me it looks like it should work, but it isn't so I guess I'm wrong.

And ofc I have in my Startup.cs

services.AddEntityFrameworkNpgsql().AddDbContext<IdentityContext>(options =>
    options.UseNpgsql(Configuration.GetConnectionString("IdentityConnection")));

EDIT IdentityContext class:

  public class IdentityContext : DbContext
  {
    public IdentityContext(DbContextOptions<IdentityContext> options) : base(options)
    {
      while (!Debugger.IsAttached)
      {
        Thread.Sleep(100);
      }
    }
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
      modelBuilder.Entity<User>().HasIndex(user => user.Email).IsUnique();
      modelBuilder.Entity<User>().HasIndex(user => user.Username).IsUnique();
    }
  }

EDIT2. Verbose migration

Using project '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj'.
Using startup project '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj'.
Writing '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/obj/CrossX.Identity.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpCq3PQa.tmp /verbosity:quiet /nologo /home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj
Writing '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/obj/CrossX.Identity.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpR48yu8.tmp /verbosity:quiet /nologo /home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj
dotnet build /home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj /verbosity:quiet /nologo

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

Time Elapsed 00:00:01.17
dotnet exec --depsfile /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.deps.json --additionalprobingpath /home/msek/.nuget/packages --runtimeconfig /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.runtimeconfig.json /home/msek/.dotnet/tools/.store/dotnet-ef/2.2.2/dotnet-ef/2.2.2/tools/netcoreapp2.2/any/tools/netcoreapp2.0/any/ef.dll migrations add Init --assembly /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.dll --startup-assembly /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.dll --project-dir /home/msek/Projects/inz/CrossX/src/CrossX.Identity/ --language C# --working-dir /home/msek/Projects/inz/CrossX/src/CrossX.Identity --verbose --root-namespace CrossX.Identity
Using assembly 'CrossX.Identity'.
Using startup assembly 'CrossX.Identity'.
Using application base '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2'.
Using working directory '/home/msek/Projects/inz/CrossX/src/CrossX.Identity'.
Using root namespace 'CrossX.Identity'.
Using project directory '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding IWebHost accessor...
No CreateWebHostBuilder(string[]) method was found on type 'CrossX.Identity.Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'IdentityContext'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'IdentityContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728 ---> 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 Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_3.<FindContextTypes>b__13()
   --- End of inner exception stack trace ---
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_3.<FindContextTypes>b__13()
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 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.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Unable to create an object of type 'IdentityContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728


Solution 1:[1]

My problem was that I didn't set my api project from the solution as Startup Project so it wouldn't find any Startup.cs or sth like that.

Solution 2:[2]

Make sure you have default constructor of IdentityContext without parameters. It should work.

Solution 3:[3]

If you are using the CLI,

When you have a solution with 2 projects API/WebApp and a DataAcess project you can pass in the options on the command line.

My_Solution
       |DataAccess_Project
       |-- DbContext.cs
       |WebApp_Project
       |-- Startup.cs

Change into the solution directory

CD My_Solution

dotnet ef add migration InitialCreate --project DataAccess_Project --startup-project WebApp_Project

dotnet ef database update --project DataAccess_Project --startup-project WebApp_Project

Solution 4:[4]

Seems like you implemented IdentityContext but somewhere in your app its still trying to reference DbContext. Make sure Identitycontext is extending DbContext.

https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

EDIT: Implemented IDesignTimeDbContextFactory as stated in https://docs.microsoft.com/en-gb/ef/core/miscellaneous/cli/dbcontext-creation

Solution 5:[5]

If you're using the new .NET 5 top-level code feature, then it is definitely why the migration is breaking. Using top-level statements in the Program class makes it impossible for the EF Tools to access it as it includes neither a namespace nor a class name.

Top-level statements:

Console.WriteLine("Hello, World!");

Classic Program class:

namespace MyApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

If this is the case, then just go back to the classic pattern.

Solution 6:[6]

Create a method in the Program class named CreateWebHostBuilder. Move your main method body to that class and call that class from the Main method. New implementation would be:

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    ServiceHost.Create<Startup>(args)
                .UseRabbitMq()
                .Build()
                .Run();

ef tool looks around CreateWebHostBuilder method and returns error when failed to find any.

Solution 7:[7]

Adding this variant of a solution in case it helps someone. I needed to create a migration in a simple console app and had to add an empty default .ctor to the DbContext class.

public TestContext()
{
}

public TestContext(DbContextOptions<TestContext> options) : base(options)
{
}

Solution 8:[8]

EF needs to be able to get an instance of DbContext.

From an answer here:

Make sure you set the default startup project to the WebApplication.
Then in the Package Manager Console set the Default Project to the Data project. This will use the WebApplication configuration and add migrations to the Data project.

If you're running update-database command then you'll need to set the default project to your WebAPI project where the Startup.cs file is located.

Solution 9:[9]

Just to add current info in case it helps someone on .Net 6.
In my case using .Net 6, and dotnet-ef version '6.0.4' the single key thing that made it work was ensuring the no-params constructor was present and public as in:

public TestContext()
{
}

My problem was that VS Code had created a protected constructor for me.
Some things that I tried that made NO difference:-

  • if your console app uses top-level statements or not,
  • NO need to have a TestContext(options) constructor.

Solution 10:[10]

In my case, the problem was that Startup was not being detected in the way it was set in program:

public static IWebHostBuilder CreateWebHostBuilder(string[] args, Type startup)
{
   return WebHost.CreateDefaultBuilder(args).UseStartup(startup);
}

passing the type directly solved the problem:

.UseStartup<Startup>()

Solution 11:[11]

it's probably giving to you this problem, because you are using layered architecture. so you must factory desing pattern .for examlpe your context class must be like this below ;

     public ModelContext(DbContextOptions<ModelContext> options) : base(options){}

       public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ModelContext>
    {

                DbContextOptionsBuilder<ModelContext> builder = new DbContextOptionsBuilder<ModelContext>();               
                IConfiguration config = new ConfigurationBuilder()
                .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(),"C:/Users/mücteba/source/repos/market/Market.API")) 
                       
                .AddJsonFile("appsettings.json")
                .Build();
           builder.UseSqlServer(config.GetConnectionString("SQLProvider"));
            return new ModelContext(builder.Options);
     }
  }
      DbSet<Personel> personels { get; set; }

this class is required if you use layered architecture!!!!

Solution 12:[12]

In your classes using DbContext set the constructor like:

public class NameContext: DbContext
{
    public NameContext(DbContextOptions<NameContext> options) : base(options)
    { }
}

Resource:
https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/

Solution 13:[13]

in my case the reason of issue was the incorrect path to the dbsettings.json file. This path is should be written in the Startup.cs file.

 public Startup(Microsoft.AspNetCore.Hosting.IHostingEnvironment hostEnv)
    {
        _confString = new ConfigurationBuilder().SetBasePath(hostEnv.ContentRootPath).AddJsonFile("dbsettings.json").Build();
    
    }

Solution 14:[14]

Improving screamin's answer

I have a project structure like below

Solution

  • X.Api
  • ...
  • ...
  • X.Repository

My migrations are under X.Repository and my startup project is X.Api. After setting everything decently, without any code errors, I could not run my migrations using the command below

dotnet ef migrations add CreateABCTable 

Applying the solution screamin suggested, I could run my migrations. I have used the command below

dotnet ef migrations add CreateABCTable --project X.Repository.csproj --startup-project ../X.Api/X.Api.csproj