0

I have created a generic repository that I want to be used in a service.

public abstract class AbstractBaseRepository<TEntity, TEntityKey>
        : IBaseRepository<TEntity, TEntityKey>
        where TEntity : class, IBaseEntity<TEntityKey>, new() { /* some code */ }

And the interface:

public interface IBaseRepository<TEntity, TEntityKey> { /* some code */ }

On my service I inject the repository like this:

public class TenantsService : AbstractBaseService<TenantEntity, int>
{
    public TenantsService(IBaseRepository<TenantEntity, int> tenantsRepository)
        : base(tenantsRepository) { }
}

On my startup, on the ConfigureServices method, I have:

services.AddScoped(typeof(IBaseRepository<,>), typeof(AbstractBaseRepository<,>));  

I added this startup code based on the following two answers:

https://stackoverflow.com/a/33567396

https://stackoverflow.com/a/43094684

When I run the application I am getting the following error:

Cannot instantiate implementation type 'Playground.Repositories.Base.AbstractBaseRepository`2[TEntity,TEntityKey]' for service type 'Playground.Repositories.Base.IBaseRepository`2[TEntity,TEntityKey]'

Kirk Larkin
  • 84,915
  • 16
  • 214
  • 203
João Paiva
  • 1,937
  • 3
  • 19
  • 41
  • Have you tried AddSingleton in place of AddScoped in startup.cs ? – Wit Wikky Nov 01 '18 at 12:31
  • 4
    You're asking the DI container to instantiate an *`abstract`* class, which, [by definition](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract), *can't be instantiated*. – Kirk Larkin Nov 01 '18 at 12:34
  • That makes sense. Isn't there a way to specify that we want the interface to resolve to any class that extends a given class? In this case any class that extends the AbstractBaseRepository? – João Paiva Nov 01 '18 at 13:08
  • For extra functionality like that, see [Default service container replacement](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1#default-service-container-replacement) in the docs. Another option is to use something like [Scrutor](https://github.com/khellang/Scrutor). – Kirk Larkin Nov 01 '18 at 14:33
  • What you're asking for is whether there is an _assembly scanning feature that allows you to auto-register all non-generic implementations of your generic abstraction_. Answer is: no, such feature does not exist out of the box. I agree with @KirkLarkin, Scrutor adds this missing functionality on top of ASP.NET Core's built-in container. – Steven Nov 01 '18 at 16:28

1 Answers1

1

Try this:

services.AddScoped(typeof(IBaseRepository<TenantEntity, int>), typeof(TenantsService));

As Kirk Larkin mentioned in the comments, you're telling it to instantiate an abstract class for services.AddScoped(typeof(IBaseRepository<,>), typeof(AbstractBaseRepository<,>)); which it can't do.

Shelby115
  • 2,816
  • 3
  • 36
  • 52