Autofac register and resolve with Names
Instead of registering your services as "named", you may want to use "keyed" services. There is no way to specify services by their names. But you can use IIndex<TKey, TService>
to retrieve a dictionary-like object with keyed services of specified type. So you can register:
builder.RegisterType<Service1>().Keyed<IService>("key1");
builder.RegisterType<Service2>().Keyed<IService>("key2");
builder.RegisterType<Service3>().Keyed<IService>("key3");
builder.RegisterType<Service4>().Keyed<IService>("key4");
builder.RegisterType<Service5>().Keyed<IService>("key5");
Later, in your constructor, you can inject:
public Test(IIndex<string, IService> serviceDictionary)
{
var service1 = serviceDictionary["key1"];
}
I used string
objects as keys, but you can introduce e.g. enum and use it as a key.
EDIT:
If you want to narrow down available services for some classes, you can e.g. introduce different enum types as keys.
enum ServicesA { A1, A2, A3 }
enum ServicesB { B1, B2 }
Then, registratrions:
builder.RegisterType<Service1>().Keyed<IService>(ServicesA.A1);
builder.RegisterType<Service2>().Keyed<IService>(ServicesA.A2);
builder.RegisterType<Service3>().Keyed<IService>(ServicesA.A3);
builder.RegisterType<Service4>().Keyed<IService>(ServicesB.B1);
builder.RegisterType<Service5>().Keyed<IService>(ServicesB.B2);
Now, if you inject IIndex<SerivcesA, IService>
, only Service1
, Service2
and Service3
would be available, for IIndex<SerivcesB, IService>
it would be Service4
and Service5
.
You can chain Keyed
registration so if you join both registrations from above to
builder.RegisterType<Service1>().Keyed<IService>(ServicesA.A1).Keyed<IService>("key1");`
etc., you could use both IIndex<YourEnum, IService>
with only some of IService
implementations or IIndex<string, IService>
with all of them.