简体   繁体   中英

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?

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>>();

//...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM