I am trying to use Dependency injection in following way, however I am getting below error
InvalidOperationException: Unable to resolve service for type '' while attempting to activate ''.
What I am trying to achieve is, I have defined some common methods in generic interface and other methods where data driven logic will differ written down in repository specific interface Like ICustomerRepository.
And from controller these common and specific methods should be called. However as stated I am getting the above error when trying to execute API.
The reason why I kept generic repositories as those should not get added in StartUp.cs as and when added per repository.
So, how can execute generic and non generic methods through repository specific interface ?
Any help on this appreciated !
Below is my code
IGenericRepository.cs
public interface IGenericRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> GetAll();
TEntity GetById(int id);
void Create(TEntity entity);
Task Update(int id, TEntity entity);
TEntity Delete(int id);
}
GenericRepository.cs
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
private readonly DbContext dbContext;
public GenericRepository(DbContext dbContext)
{
this.dbContext = dbContext;
}
public void Create(TEntity entity)
{
dbContext.Set<TEntity>().Add(entity);
dbContext.SaveChanges();
}
public TEntity Delete(int id)
{
throw new NotImplementedException();
}
public IEnumerable<TEntity> GetAll()
{
return dbContext.Set<TEntity>().ToList();
}
public TEntity GetById(int id)
{
return dbContext.Set<TEntity>().Find(id);
}
public Task Update(int id, TEntity entity)
{
throw new NotImplementedException();
}
IEnumerable<TEntity> IGenericRepository<TEntity>.GetAll()
{
return dbContext.Set<TEntity>().ToList();
}
}
ICustomerRepository.cs
public interface ICustomerRepository : IGenericRepository<Customer>
{
Task<Customer> GetCustomerDetails();
}
CustomerRepository.cs
public class CustomerRepository : GenericRepository<Customer>, ICustomerRepository
{
private readonly BaseDBContext _dbContext;
public CustomerRepository(BaseDBContext dbContext)
: base(dbContext)
{
_dbContext = dbContext;
}
public Task<Customer> GetCustomerDetails()
{
throw new NotImplementedException();
}
}
Customer.cs
public class Customer
{
[Key]
public int CustId { get; set; }
public string CustomerName { get; set; }
public string City { get; set; }
public string Designation { get; set; }
}
StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFrameworkSqlServer().AddDbContext<BaseDBContext>();
services.Configure<DBConfiguration>(Configuration.GetSection("DBConfiguration"));
services.AddScoped<DbContext, BaseDBContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));
}
CustomerController.cs
private readonly ICustomerRepository custRepository;
public ValuesController(IOptions<DBConfiguration> dBConfiguration, ICustomerRepository _custRepository)
{
custRepository= _custRepository;
}
ICustomerRepository, which the container knows nothing about. Hence the error. Just because you registered the generic interface does not mean it will know about the derived interface and its implementation.DbContextis your unit of work, and eachDbSetis a repository. When you use an ORM like EF, you are simply opting to use a third-party DAL. Why in heaven people think they need to wrap their own DAL around that is beyond me. Normally, someone will chime in: to abstract the EF dependency. Really? Your repository depends on it directly, and you're even leaking it into the appStartup. Doesn't seem very "abstracted" to me.