Get a list of all registered objects implementing a certain interface
If you have
container.Register(c => new A()).As<ISomeInterface>();
container.Register(c => new B()).As<ISomeInterface>();
Then when you do
var classes = container.Resolve<IEnumerable<ISomeInterface>>();
You will get a variable that is a list of ISomeInterface, containing A and B
I was looking for a similar solution for registrations done as follows:
builder.RegisterType<Bamboo>().As<IExoticTree>();
// and/or
builder.RegisterType<SolidOak>().Keyed<IMountainTree>(key);
where IExoticTree
and IMountainTree
inherit from a common ITree
interface.
With those, the service type (e.g. registered interface) is different from the LimitType
and hence, the proposed solution is not applicable.
I got inspired by the accepted solution to manage these as well with the following code:
IEnumerable<ITree> instances = scope.ComponentRegistry.Registrations
.Where(r => typeof(ITree).IsAssignableFrom(r.Activator.LimitType))
.Select(r => r.Services.First())
.Select(s => scope.ResolveService(s) as ITree)
.Distinct();
Hope it helps someone ^^
Here is how I did it.
var l = Container.ComponentRegistry.Registrations
.SelectMany(x => x.Services)
.OfType<IServiceWithType>()
.Where(x =>
x.ServiceType.GetInterface(typeof(ISomeInterface).Name) != null)
.Select(c => (ISomeInterface) c.ServiceType);
Just tried this, works and does not depend on lifetime context:
Enumerate types using Activator instead
var types = con.ComponentRegistry.Registrations
.Where(r => typeof(ISomeInterface).IsAssignableFrom(r.Activator.LimitType))
.Select(r => r.Activator.LimitType);
Then to resolve:
IEnumerable<ISomeInterface> lst = types.Select(t => con.Resolve(t) as ISomeInterface);