avolkmann
avolkmann

Reputation: 3105

.NET Core Dependency Injection - Resolve implementations and IEnumerable of interface

I have an interface IMyType with several implementations SomeMyType, OtherMyType.

I want to use both the concrete types, as well as an IEnumerable of all types that implement the IMyType interface.

These could be the declarations in a service.

private readonly IEnumerable<IMyType> instances;
private readonly SomeMyType someType;
private readonly OtherMyType otherType;

One way to make this work is by using the following extension:

public static IServiceCollection AddMyType<T>(this IServiceCollection serviceCollection)
    where T : class, IMyType =>
    serviceCollection
        .AddSingleton(typeof(IMyType), typeof(T))
        .AddSingleton(typeof(T));

This adds a singleton for both the concrete type and the interface.

Is this a good way to configure the dependencies?

Are there other ways to improve the solution? I am thinking if this will create two instances of T, or if the framework tries to resolve the second singleton with the first T.

Upvotes: 1

Views: 1292

Answers (1)

Nkosi
Nkosi

Reputation: 247008

Register the class and when registering the interface, use the delegate factory to get the registered class.

public static IServiceCollection AddMyType<T>(this IServiceCollection serviceCollection)
    where T : class, IMyType =>
    serviceCollection
        .AddSingleton<T>();
        .AddSingleton<IMyType>(sp => sp.GetService<T>());

Which would be used like

services.AddMyType<SomeMyType>();
services.AddMyType<OtherMyType>();

For resolving your services in this scenario, in order to get all the registered IMyType, inject IEnumerable<IMyType>

private readonly IEnumerable<IMyType> instances;

public MyClass(IEnumerable<IMyType> instances) {
    this.instances = instances;

    //...
}

The concrete types, having also been registered can be explicitly injected as needed as well

private readonly SomeMyType someType;

public MyClass(SomeMyType someType) {
    this.someType = someType;

    //...
}

Upvotes: 2

Related Questions