I'm using Autofac in an application to manage dependencies. I have an interface and a number of implementations for the interface. The actual implementations are registered as keyed services in the container.
What I would like to do is to resolve an instance of every service (hence the IEnumerable) that are registered with a specific keytype (hence the typed registration).
If I use the container directly, it works:
container.ResolveKeyed<IEnumerable<IService>>(MyServiceGroups.Group1);
// This returns the a list of IService implementor objects, that were previously registered with the given key
However, if I use the [KeyFilter]
attribute in my constructors to resolve the dependencies, it has no effect and I get the list of all registered services, regardless of the value used at the keyed registrations.
public class MyBigService([KeyFilter(MyServiceGroups.Group1)] services)
{
// here services contains one from every type, not just the ones registered with that particular key
}
What am I doing wrong? Is there any way to make this work? I could probably combine the Func and IEnumerable types and resolve from the container that way manually (since that works), but I'd like to keep this structure.
EDIT Concrete example with code:
public class SubserviceModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SubServiceA>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeX);
builder.RegisterType<SubServiceB>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeX);
builder.RegisterType<SubServiceC>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeY);
builder.RegisterType<SubServiceD>().As<ISubService>().Keyed<ISubService>(ServiceType.TypeY);
}
}
public class ServiceModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Service1>();
builder.RegisterType<Service2>();
}
}
public abstract class ServiceBase
{
public ServiceBase(IEnumerable<ISubService> subServices) {/*...*/}
}
public class Service1
{
public ServiceA([KeyFilter(ServiceGroup.ServiceTypeX)] IEnumerable<ISubService> subServices)
: base(subServices) { /* ... */ }
}
public class Service2
{
public ServiceB([KeyFilter(ServiceGroup.ServiceTypeY)] IEnumerable<ISubService> subServices)
: base(subServices) { /* ... */ }
}