0

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;
        }
8
  • 1
    You are injecting 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. Commented Jul 18, 2019 at 15:25
  • @Nkosi Agree but then how can achieve this ? Commented Jul 18, 2019 at 15:25
  • Someone already provided a valid answer Commented Jul 18, 2019 at 15:26
  • @Nkosi Yeah but I am not looking in that way Commented Jul 18, 2019 at 15:29
  • 2
    The hoops people go through for completely unnecessary things. You can save yourself a ton of time, effort and energy by simply not using repositories. DbContext is your unit of work, and each DbSet is 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 app Startup. Doesn't seem very "abstracted" to me. Commented Jul 18, 2019 at 15:55

1 Answer 1

3

Add this to your StartUp.cs

services.AddScoped<ICustomerRepository, CustomerRepository>();
Sign up to request clarification or add additional context in comments.

3 Comments

Nope, I don't want to do in that way... It will result in adding number of repositories in startup.cs file. I want to implement in generic way
@XamDev Then do a registration by convention. You can choose to register all concrete types as the interfaces they implement, or you can add a marker interface to only do that for certain types.
This blog entry shows how to use Scrutor to do that with Microsoft.Extensions.DependencyInjection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.