DEV
DEV

Reputation: 131

System.MissingMethodException Constructor on type xxx not found

I have a generic method, this method will receive a dbcontext type. This generic method should create a new instance from the received context type and return it.

a Dbcontext example:

  class SchoolContext:DbContext
    {

        public SchoolContext(DbContextOptions<SchoolContext> dbContextOptions):base(dbContextOptions)
        {
            
        }

        public DbSet<Branche> Branches { get; set; }
        public DbSet<Student> Students { get; set; }
    }

What i tried:

public static TContext GetInstance<TContext>(string connectionString) where TContext:DbContext
{
    var      optionsBuilder = new DbContextOptionsBuilder();
    optionsBuilder.UseSqlServer(connectionString);
    TContext context = Activator.CreateInstance(typeof(TContext), optionsBuilder.Options) as TContext;

    return context;
}

Erros I got :

 System.MissingMethodException: 'Constructor on type 'SchoolContext' not found.'

so please how I can fix this issue ?

Upvotes: 0

Views: 5417

Answers (2)

Scott Hannen
Scott Hannen

Reputation: 29222

This isn't generic:

var optionsBuilder = new DbContextOptionsBuilder();

So this can't be generic either:

optionsBuilder.Options

So if you have a constructor that requires a specific generic type as an argument: public SchoolContext(DbContextOptions<SchoolContext> dbContextOptions)

...then that means you're not passing what this constructor expects. So Activator.CreateInstance is looking for a constructor that takes whatever optionsBuilder.Options is (non-generic options), but it can't find one. That's the missing method.

You'll need to figure out how to create an instance of DbContextOptions<SchoolContext>.

If you change this

var optionsBuilder = new DbContextOptionsBuilder();

to

var optionsBuilder = new DbContextOptionsBuilder<SchoolContext>();

then the Options property will return the generic type you need, DbContextOptions<SchoolContext>.

Upvotes: 0

David Browne - Microsoft
David Browne - Microsoft

Reputation: 89141

Almost there. You just need to start with a DbContextOptionsBuilder<TContext> to create a DbContextOptions<SchoolContext> for the constructor, like this:

public static TContext GetInstance<TContext>(string connectionString) where TContext : DbContext
{
    var optionsBuilder = new DbContextOptionsBuilder<TContext>();
    optionsBuilder.UseSqlServer(connectionString);
    TContext context = (TContext)Activator.CreateInstance(typeof(TContext), optionsBuilder.Options);

    return context;
}

Upvotes: 2

Related Questions