Keyed and generic services
Keyed services
container.Register<IStorage, BlobStorage>("blob");
container.Register<IStorage, DiskStorage>("disk");
var blob = container.Resolve<IStorage>("blob");
public sealed class Uploader([FromKeyedServices("blob")] IStorage storage);
public sealed class Named([ServiceKey] string key); // receives the key it was resolved with
Registering with KeyedService.AnyKey provides a fallback for any key, following Microsoft’s semantics.
Open generics
container.Register(typeof(IRepository<>), typeof(Repository<>)).AsScoped();
var orders = container.Resolve<IRepository<Order>>();
A closed registration (IRepository<Order>) wins over the open one. Generic constraints are honored: an open generic that can’t close over a type is skipped.
Many implementations
Register replaces; RegisterEnumerable appends:
container.RegisterEnumerable<IValidator, NotEmptyValidator>();
container.RegisterEnumerable<IValidator, MaxLengthValidator>();
IReadOnlyList<IValidator> all = container.ResolveAll<IValidator>(); // registration order
public sealed class Form(IEnumerable<IValidator> validators); // injected the same way
A single Resolve<IValidator>() returns the last registration.