Jeremy Thompson
Jeremy Thompson

Reputation: 65554

Cannot instantiate implementation type Repository`1[TDBContext]' for service type 'IRepository'.'

I'm hitting the error in the title when running this setup code:

Program.cs:

builder.Services.AddDbContext<TDBContext>(opt => opt.UseInMemoryDatabase("My"));

// Can't work out how to wire up the Repository?
//builder.Services.AddScoped<IRepository>(p => new TDBContext());
//builder.Services.AddScoped<IRepository, Repository>();
builder.Services.AddScoped(typeof(IRepository), typeof(Repository<>));
//builder.Services.AddScoped(typeof(IRepository), typeof(Repository<TDBContext>));

builder.Services.AddScoped<IMyService, MyService>();

var app = builder.Build();  //ERROR HERE!

Service and Repository:

public class MyService : IMyService
{
    private readonly IRepository _repository;
    
    public MyService(IRepository repository)
    {          
        _repository = repository;
    }
}
    
public class Repository<TDBContext> : IRepository where TDBContext : DbContext
{
    protected DbContext dbContext;

    public Repository(DbContext context)
    {
        dbContext = context;
    }
    public async Task<int> CreateAsync<T>(T entity) where T : class
    {
        this.dbContext.Set<T>().Add(entity);
        return await this.dbContext.SaveChangesAsync();
    }
    //.....
}


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

    public virtual DbSet<MyTransaction> Transactions { get; set; } = null!;

    public TDBContext()
    {
    }
}

I've tried a few suggestions found on here shown as code comments but no luck. Can someone please clarify how I wire up the Repository and get the DI to load in the DbContext?

Upvotes: 0

Views: 4560

Answers (2)

Anubhav verma
Anubhav verma

Reputation: 21

I was having the same problem, but the reason for my error was that I was configuring both the interface and implementation separately then again doing the same for the binding configuration. Removing the separate configuration solved it.

Upvotes: 0

Nkosi
Nkosi

Reputation: 247088

Check the repository constructor. The container does not know how to handle DbContext as dependency when resolving the repository.

Did you mean to use the generic argument type instead?

Also the naming of the generic parameter might cause confusion.

public class Repository<TContext> : IRepository where TContext : DbContext {
    protected DbContext dbContext;

    public Repository(TContext context) {
        dbContext = context;
    }

    public async Task<int> CreateAsync<T>(T entity) where T : class {
        this.dbContext.Set<T>().Add(entity);
        return await this.dbContext.SaveChangesAsync();
    }

    //.....
}

And the registration will need to use the closed type

//...

builder.Services.AddScoped<IRepository, Repository<TDBContext>>();

//...

Upvotes: 3

Related Questions