Reputation: 3105
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
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