System.InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbSet`1[Entities.Product]' while attempting to activate 'Drin.Data.Repositories.GenericRepository`1[Entities.Product]'.
I getting this error while try to execute controller method
public class SampleDbContext : DbContext
{
public SampleDbContext(DbContextOptions<SampleDbContext> options) : base(options) {
}
public DbSet<Category> Category { get; set; }
public DbSet<Product> Product { get; set; }
public DbSet<ProductFeature> ProductFeature { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
builder.Entity<ProductFeature>().HasData(
new ProductFeature { Id = 1, Colour = "Black", Weight = 40, ProductId = 1 },
new ProductFeature { Id = 2, Colour = "Blue", Weight = 10, ProductId = 2 });
base.OnModelCreating(builder);
}
}
Program.cs code file like that
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
builder.Services.AddScoped(typeof(IService<>), typeof(Service<>));
builder.Services.AddAutoMapper(typeof(MapProfile));
builder.Services.AddDbContext<SampleDbContext>(x =>
{
x.UseSqlServer(builder.Configuration.GetConnectionString("DevConnection"), options =>
{
options.MigrationsAssembly(Assembly.GetAssembly(typeof(SampleDbContext)).GetName().Name);
});
});
GenericRepository Like that also:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private readonly SampleDbContext context;
private readonly DbSet<T> dbSet;
public GenericRepository(SampleDbContext context, DbSet<T> dbSet)
{
this.context = context;
this.dbSet = context.Set<T>();
}
public async Task AddAsync(T entity)
{
await dbSet.AddAsync(entity);
}
}
CodePudding user response:
It seems that you are injecting DbSet<Product>
into your repository. Usual approach is to register context only in the DI with AddDbContext
or AddDbContextFactory
and resolve context in the repository:
public class SomeClassDependingOnDb
{
private readonly SomeAppDbContext _context;
public class SomeClassDependingOnDb(SomeAppDbContext context) => _context = context;
...
}
Then you can use it to access specific DbSet
via generic type via Set<TEntity>
method - _context.Set<TEntity>
(if holding method/type is generic of TEntity
).
See more in the docs:
UPD
Taking in account everything written earlier you repo should look like this (remove the DbSet<T> dbSet
parameter):
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private readonly SampleDbContext context;
private readonly DbSet<T> dbSet;
public GenericRepository(SampleDbContext context)
{
this.context = context;
this.dbSet = context.Set<T>();
}
public async Task AddAsync(T entity)
{
await dbSet.AddAsync(entity);
}
}