0
votes

I have an ASP.NET Core MVC application which uses Entity Framework Core O/RM. I am implementing generic repository pattern in my application. There are two entities, Employee & Department. There is one context class EmployeeDepartmentDetails.There's an interface IGenericRepository which is implemented by GenericRepository. GenericRepository has a Dependency Injection of EmployeeDepartmentDetails.My Controller EmployeeController has a Dependency Injection of IGenericRepository.

IGenericRepository.cs -

public interface IGenericRepository<TEntity> where TEntity : class
{
    //...
}

EmployeeDepartmentDetail.cs

public class EmployeeDepartmentDetail : DbContext
{

    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Department { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=JARVIS\SQLEXPRESS;Database=EmpDep;Trusted_Connection=True;");
    }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }

}

GenericRepository.cs - Here EmployeeDepartmentDetails is my context class which inherits DBContext class-

public class GenericRepository<TEntity> :IGenericRepository<TEntity> where TEntity : class
{
    DbSet<TEntity> _dbSet;
    // Dependency Injection 
    private readonly EmployeeDepartmentDetail _employeeDepartmentDetail; 
    public GenericRepository(EmployeeDepartmentDetail employeeDepartmentDetail)
    {
        _employeeDepartmentDetail = employeeDepartmentDetail;
        _dbSet = _employeeDepartmentDetail.Set<TEntity>();
    } 

    //... 
}

Program.cs -

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

StartUp.cs -

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); 
}

EmployeeController.cs -

public class EmployeeController : Controller
{
    private readonly IGenericRepository<Employee> _genericRepository;
    public EmployeeController(IGenericRepository<Employee> genericRepository)
    {
        _genericRepository = genericRepository;
    } 

    //... 
}

I am getting this exception in browser, when I am running my application -

InvalidOperationException: A suitable constructor for type 'InfrastructureLayer.GenericRepository.Implementation.GenericRepository`1[Entities.Employee]' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor. Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)

I am unable to understand the exception, I don't know what I am doing wrong here. I know I have pasted lot of code, but I don't even know how to explain the exception.

1
Where do you register EmployeeDepartmentDetails? - mtkachenko
@mtkachenko in GenericRepository class - Nihal Singh
Basically you are trying to inject EmployeeDepartmentDetail, but you never defined what that is or how your app is supposed to get that dependency. This is done in startup.cs. Give me a sec and I will have an example for you. - Patrick Mcvay
Try using this services.AddScoped(IGenericRepository<Employee>, GenericRepository<Employee>); According to the exception I believe this might be your problem. - Patrick Mcvay
@PatrickMcvay that is already implemented. As I have two entities Employee and Department, I had to leave <> empty - Nihal Singh

1 Answers

0
votes

According to the exception, I'm sure that your program cannot instantiate the GenericRepository.

This is because the GenericRepository is dependent on your EmployeeDepartmentDetail which is your DbContext from EntityFramework Core. And this DbContext has not been registered to your IoC Container.

I had exactly the same exception as yours after I disabled the service registration of my DbContext. Please refer to the screenshot in the following link: enter image description here

In order to resolve this exception, let's register your DbContext or EmployeeDepartmentDetail to your IoC container by checking your Startup.cs -> ConfigureServices and added something like this:

services.AddDbContext<SchoolContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));