How do you register and resolve multiple implementations of the same interface in ASP.NET Core DI?
Quick Answer
Register each implementation against the interface; the container collects them. Inject IEnumerable<INotifier> to get all of them, or use keyed services (.NET 8+) — AddKeyedScoped<INotifier, EmailNotifier>("email") and [FromKeyedServices("email")] — to resolve a specific one. Resolving INotifier plainly gives you the last registered.
If I register two implementations against INotifier, the container keeps both — resolving INotifier directly just gives me the last one registered, but injecting IEnumerable<INotifier> gives me all of them, which is what I want for something like sending a notification through every channel. If I need to pick a specific one, .NET 8 has keyed services: I register with a key and consume it with [FromKeyedServices("email")]. Before .NET 8 I'd inject a factory delegate or write a small resolver that switches over the IEnumerable.
- All of them:
services.AddScoped<INotifier, EmailNotifier>(); services.AddScoped<INotifier, SmsNotifier>();then injectIEnumerable<INotifier>and loop — good for a notification fan-out or a validation pipeline. - A specific one by key (.NET 8+):
AddKeyedScoped<INotifier, EmailNotifier>("email"); consume with[FromKeyedServices("email")] INotifier norsp.GetRequiredKeyedService<INotifier>("email"). - Pre-.NET 8: a factory delegate (
Func<string, INotifier>) or a small resolver class that switches over the injectedIEnumerable. TryAddEnumerableregisters an implementation only if that exact type isn't already registered — useful in libraries.
// all implementations
builder.Services.AddScoped<INotifier, EmailNotifier>();
builder.Services.AddScoped<INotifier, SmsNotifier>();
public class AlertService(IEnumerable<INotifier> notifiers)
{
public Task RaiseAsync(Alert a) =>
Task.WhenAll(notifiers.Select(n => n.SendAsync(a)));
}
// a specific one (.NET 8+)
builder.Services.AddKeyedScoped<INotifier, EmailNotifier>("email");
public class Welcome([FromKeyedServices("email")] INotifier email) { }