Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection for generic interface with two type arguments

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;
    }
}
like image 224
Carlos Jimenez Bermudez Avatar asked Jan 20 '21 02:01

Carlos Jimenez Bermudez


People also ask

How do you declare a generic interface as contravariant?

You can declare a generic type parameter contravariant by using the in keyword. The contravariant type can be used only as a type of method arguments and not as a return type of interface methods. The contravariant type can also be used for generic constraints.

How to implement generic interface in C#?

Declaring Variant Generic Interfaces You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.

How to Get generic type in C#?

If you call the GetGenericTypeDefinition method on a Type object that already represents a generic type definition, it returns the current Type. An array of generic types is not itself generic. In the C# code A<int>[] v; or the Visual Basic code Dim v() As A(Of Integer) , the type of variable v is not generic.

Can a generic type be an interface?

Java Generic Classes and SubtypingWe can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.


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));
like image 152
TheGeneral Avatar answered Oct 20 '22 15:10

TheGeneral