-
Notifications
You must be signed in to change notification settings - Fork 7
Description
I have an aggregate service containing interfaces that are only registered with keys (using Keyed<>()). Furthermore, each interface within the aggregate has the same number of concrete implementations, which are all mapped to the same key. Essentially it's a non-jagged 2D array of registrations.
I'd like the ability to resolve the aggregate service with IIndex, which would forward the key to the resolution of the services within it.
I have an example that demonstrates the behavior I'm looking for, which I'll provide below.
internal interface IMyService2
{
void PrintInfo();
}
internal interface IMyService1
{
void PrintInfo();
}
internal class MyService1Impl1 : IMyService1
{
public void PrintInfo()
{
Console.WriteLine(" - MyService1Impl1");
}
}
internal class MyService1Impl2 : IMyService1
{
public void PrintInfo()
{
Console.WriteLine(" - MyService1Impl2");
}
}
internal class MyService2Impl1 : IMyService2
{
public void PrintInfo()
{
Console.WriteLine(" - MyService2Impl1");
}
}
internal class MyService2Impl2 : IMyService2
{
public void PrintInfo()
{
Console.WriteLine(" - MyService2Impl2");
}
}
internal interface IMyAggregateServices
{
public IMyService1 Service1 { get; init; }
public IMyService2 Service2 { get; init; }
}
public static class Program
{
public static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<MyService1Impl1>().Keyed<IMyService1>("one");
builder.RegisterType<MyService1Impl2>().Keyed<IMyService1>("one");
builder.RegisterType<MyService2Impl1>().Keyed<IMyService2>("two");
builder.RegisterType<MyService2Impl2>().Keyed<IMyService2>("two");
builder.RegisterAggregateService<IMyAggregateServices>();
var container = builder.Build();
var index = container.Resolve<IIndex<string, IMyAggregateServices>>();
var aggregateServices = index["one"];
Console.WriteLine("Print Service1:");
aggregateServices.Service1.PrintInfo();
Console.WriteLine("Print Service2:");
aggregateServices.Service2.PrintInfo();
}
}Above, I expect the following output:
Print Service1:
- MyService1Impl1
Print Service2:
- MyService2Impl1
Obviously, the code above won't even execute. Instead, I get this exception:
Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'one (ConsoleApp1.IMyAggregateServices)' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
If there's a reasonable workaround, I'm open to that as well. I'm sure I could implement my own concrete aggregate class to simulate this somehow, but I was hoping native support for this would be added.