Dependency injection for generic interface with two type arguments

Viewed 2844

So I am trying to inject a generic repository that receives as generic types both the entity type and the type of key the entity uses.

The declaration looks something like this:

public class GenericRepository<KeyType, T> : BaseRepository<T, NpgsqlConnection>, IGenericRepository<KeyType, T> 
        where T : class
        where KeyType : struct

So I try to inject them like this:

services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));

That works for when there is only one generic type, but not for two. I get the following error:

Using the generic type 'GenericRepository<KeyType, T>' requires 2 type arguments

Does anyone have a clue how to solve this?

I know I could make classes for each one, but I'd like to inject it like this:

public class RestaurantTypesService : IRestaurantTypesService
{
    private readonly IGenericRepository<long, RestaurantType> _restaurantTypeRepository;

    public RestaurantTypesService(IGenericRepository<long, RestaurantType> repository)
    {
        _restaurantTypeRepository = repository;
    }
}
1 Answers

This is known as an unbound type.

Multiple Unbound Generic Type parameters are denoted by the commas.

  • 1 - SomeType<>

  • 2 - SomeType<,>

  • N - SomeType<,(n-1)>

Basically, it should be as simple as

service.AddTransient(typeof(IGenericRepository<,>), typeof(GenericRepository<,>));

The worlds most contrived example

public interface IGenericRepository<T, T2> { }

public class GenericRepository<T, T2> : IGenericRepository<T, T2> { }

public class Bob
{
   private IGenericRepository<int, int> _something;

   public Bob(IGenericRepository<int,int> something)
   {
      _something = something;
      Console.WriteLine(something.GetType().Name);
   }
}

...

var service = new ServiceCollection();

service.AddTransient(typeof(IGenericRepository<,>), typeof(GenericRepository<,>));
service.AddTransient<Bob>();

var provider = service.BuildServiceProvider();
var sdfg=provider.GetService(typeof(Bob));
Related