Generic Interface, Implementation and Dependency Injection - Implementation Type Can't Be Converted To Service Type

Viewed 1269

I have the following generics (code removed for brevity, I don't think its necessary for the question):

// ## Entity interface

public interface IEntity<TPrimaryKey>
{
    TPrimaryKey Id { get; set; }
}

// ## Entity implementations

public class Entity<TPrimaryKey> : IEntity<TPrimaryKey> { ... }

public class Entity : Entity<string> { ... }

// ## Repo interfaces

public interface IAsyncRepository<TPrimaryKey, TEntity>
    where TEntity : Entity<TPrimaryKey> { ... }

public interface IAsyncRepository<TEntity> : IAsyncRepository<string, TEntity>
    where TEntity : Entity<string> {...}

// ## Repo implementations

public class AsyncRepository<TPrimaryKey, TEntity>
    : IAsyncRepository<TPrimaryKey, TEntity>
        where TEntity : Entity<TPrimaryKey> { ... }

public class AsyncRepository<TEntity> : AsyncRepository<string, TEntity>
    where TEntity : Entity { ... }

I then dependency-inject the AsyncRepositories as follows:

services.AddScoped(typeof(IAsyncRepository<>), typeof(AsyncRepository<>));
services.AddScoped(typeof(IAsyncRepository<,>), typeof(AsyncRepository<,>));

However, when I attempt to inject into my razor page using @inject IAsyncRepository<Account> accountRepository, I get an error saying:

System.ArgumentException: Implementation type 'AsyncRepository`1[Account]' can't be converted to service type 'IAsyncRepository`1[Account]'

But, if I change the declaration of the final AsyncRepository class as follows then it works:

public class AsyncRepository<TEntity> : IAsyncRepository<TEntity>
    where TEntity : Entity

Unfortunately I now have code duplication as I need to re-implement the interface.

Is there any way around this?

1 Answers

Your repository must implement IAsyncRepository<TEntity> : update your AsyncRepository<TEntity> declaration with :

public class AsyncRepository<TEntity> : AsyncRepository<string, TEntity>,
IAsyncRepository<TEntity>
where TEntity : Entity { ... }
Related