AddTransient to IServiceCollection when a generic type is unknown

Viewed 1019

In my WebApi Core, the Repository is by constructor injection.

//In the application, Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MyContext>(options => 
        options.UseSqlServer(_config["ConnectionStrings:myConnection"]));
    services.AddDataAccess<MyContext>();
    services.AddMvc();
}

//In the controller
public class ValuesController : Controller
{
    readonly IRepository<Customer> _repository;

    public ValuesController(IRepository<Customer> repository)
    {
       _repository = repository;
    }
}

See below the generic DAL. I got an error on : services.AddTransient Using the generic type 'GenericEntityRepository' requires 2 type arguments

Then I need somehting like this :

services.AddTransient(typeof(IRepository<TEntity>), typeof(GenericEntityRepository<TEntityContext, TEntity>));

but when I do this I get the errors :

  • TEntity not found
  • TEntityContext must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TContext' in the generic type or method 'GenericEntityRepository'

I don't see at all how solve this.

//In my Generic DAL
public static class ServiceCollectionExtentions
{
    public static IServiceCollection AddDataAccess<TEntityContext>(this IServiceCollection services)
        where TEntityContext : EntityContextBase<TEntityContext>
    {
        RegisterDataAccess<TEntityContext>(services);
        return services;
    }

    private static void RegisterDataAccess<TEntityContext>(IServiceCollection services)
        where TEntityContext : EntityContextBase<TEntityContext>
    {
        services.AddTransient(typeof(IRepository<>), typeof(GenericEntityRepository<>));
    }
}

public class EntityContextBase<TContext> : DbContext 
    where TContext : DbContext
{
    public EntityContextBase(DbContextOptions<TContext> options) : base(options) { }
}

public interface IRepository<TEntity>
{
    void Load();
}

public class GenericEntityRepository<TContext,TEntity> 
    : EntityRepositoryBase<TContext, TEntity> 
        where TEntity : BaseEntity, new()
        where TContext : DbContext, new()
{
    public GenericEntityRepository() : base(new TContext()) { }
}

public abstract class EntityRepositoryBase<TContext, TEntity> 
    : RepositoryBase<TContext>, IRepository<TEntity>
        where TContext : DbContext
        where TEntity : BaseEntity, new()
{
    protected EntityRepositoryBase(TContext context) : base(context)
    { }

    protected IQueryable<TEntity> QueryDb()
    {
        IQueryable<TEntity> query = Context.Set<TEntity>();

        return query;
    }

    public virtual void Load()
    {
        var result = QueryDb();
        result.Load();
    }
}

public class GenericEntityRepository<TContext,TEntity> 
    : EntityRepositoryBase<TContext, TEntity> 
        where TEntity : BaseEntity, new()
        where TContext : DbContext, new()
{
    public GenericEntityRepository() : base(new TContext()) { }
}
0 Answers
Related