Here\'s my problem: I have a container where I register concrete types as interfaces.
builder.RegisterType().As
You can very nicely encapsulate @Danielg's method so that you can let Autofac inject the type-list into a construtor. It requires you to implement the IRegistrationSource.
In my case I wanted to get all registered types derived from IConsoleCommand
like that:
public Help(TypeList commands)
{
_commands = commands;
}
I used a simple DTO-List to carry the types and the T
that I wanted to resolve them for:
public class TypeList : List
{
public TypeList(IEnumerable types) : base(types)
{
}
}
The actual registration source is implemented as following where the
from the TypeList
is used to match the type of interface that is registered and that we want to retrieve.
internal class TypeListSource : IRegistrationSource
{
public IEnumerable RegistrationsFor(Service service, Func> registrationAccessor)
{
if (service is IServiceWithType swt && typeof(TypeList).IsAssignableFrom(swt.ServiceType))
{
var registration =
new ComponentRegistration(
id: Guid.NewGuid(),
activator: new DelegateActivator(swt.ServiceType, (context, p) =>
{
var types =
context
.ComponentRegistry
.RegistrationsFor(new TypedService(typeof(T)))
.Select(r => r.Activator)
.OfType()
.Select(activator => activator.LimitType);
return new TypeList(types);
}),
services: new[] {service},
lifetime: new CurrentScopeLifetime(),
sharing: InstanceSharing.None,
ownership: InstanceOwnership.OwnedByLifetimeScope,
metadata: new Dictionary()
);
return new IComponentRegistration[] {registration};
}
// It's not a request for the base handler type, so skip it.
else
{
return Enumerable.Empty();
}
}
public bool IsAdapterForIndividualComponents => false;
}
Finally you have to add it to the builder
with:
builder.RegisterSource(new TypeListSource());
Now Autofac can resolve the types with dependency injection.