0

I have a type IReadableEntity<T> which is generic and needs a T type to be specified when we want to implement it.

Using dependency injection, I'm trying to get all the implementation of it :

using (var scope = app.Services.CreateScope())
{
    var test = scope.ServiceProvider.GetService(typeof(IEnumerable<>).MakeGenericType(typeof(IReadableEntity<>)));
}

Usually, I can get all the implementation of an interface as a list by using this pattern, but it does not work with an open generic type. I get the following error :

System.NotSupportedException : 'Cannot create arrays of open type.'

How can I get all the implementation of my interface IReadableEntity<T> regardless of the type of T ?

M. Ozn
  • 1,018
  • 1
  • 19
  • 42
  • 2
    That's the point. It is not _one_ interface. It's all of them. Each not related to the other. An `IReadableEntity` not is-a `IReadableEntity`. So you cannot put them in _one_ Enumerable. Which you could all implementations of one of each. – Fildor Jun 24 '23 at 17:30
  • 2
    If you could extract some non-generic base interface, [How to register multiple implementations of the same interface in Asp.Net Core?](https://stackoverflow.com/q/39174989) might help. – dbc Jun 24 '23 at 17:47
  • 1
    The question is missing some example code that describes *how* the `test` collection is supposed to be used. That information would help us create a picture on what it is you like to achieve and we can advice you accordingly, for instance by changing your registrations, changing the interfaces, or change how you resolve services. But it all depends on your intended usage. – Steven Jun 25 '23 at 10:32
  • Does this answer your question? [How to register dependency injection with generic types? (.net core)](https://stackoverflow.com/questions/56271832/how-to-register-dependency-injection-with-generic-types-net-core) – satnhak Jun 30 '23 at 11:45

1 Answers1

0

I would have created a new non generic interface and use that as signature.

// Empty base interface used as a signature
public interface IReadableEntity {}

public interface IReadableEntity<T> : IReadableEntity
{
  void DoSomething(T value);
}

public class SampleReadableEntity : IReadableEntity<int>
{
  public void DoSomething(int value);
}

var services = new ServiceCollection()
.AddSingleton<SampleReadableEntity >()
.AddSingleton<IReadableEntity<int>>(provider => provider.GetRequiredService<SampleReadableEntity >())
.AddSingleton<IReadableEntity>(provider => provider.GetRequiredService<SampleReadableEntity >())
.BuildServiceProvider();

var allReadableEntities = services.GetServices<IReadableEntity>();
var allIntReadableEntities = service.GetServices<IReadableEntity<int>>();
var sampleReadableEntity = services.GetService<SampleReadableEntity>();

Nikolai
  • 11
  • 1
  • 1