I'm trying to inject a specific keyed object into another's constructor, but autofac 8.0.0 raises an exception that there is a circular dependency: Circular component dependency detected: DummyComboMotor -> DummyComboMotor -> DummyComboMotor.
Here's the code the reproduces the issue. I don't see the circularity here, so I am assuming I don't understand autofac's design. Any ideas?
using Autofac;
using Autofac.Features.AttributeFilters;
public interface IMotorInterface { }
public class DummyXMotor : IMotorInterface { }
public class DummyComboMotor : IMotorInterface
{
public DummyComboMotor([KeyFilter("XMotor")] IMotorInterface x) {}
}
class TestClass
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType(typeof(DummyXMotor))
.As(typeof(DummyXMotor))
.As(typeof(IMotorInterface))
.Keyed("XMotor", typeof(IMotorInterface));
builder.RegisterType(typeof(DummyComboMotor))
.As(typeof(DummyComboMotor))
.As(typeof(IMotorInterface))
.Keyed("ComboMotor", typeof(IMotorInterface));
var container = builder.Build();
var combo = container.Resolve<DummyComboMotor>();
}
}
As indicated in the documentation Resolving with Attributes on Named and Keyed Services you must use the WithAttributeFiltering()
extension method to indicate, that attribute filtering should be used:
When you register a component that needs attribute filtering, you need to make sure to opt in. There’s a minor but non-zero performance hit to query for the attributes and do the filtering so it doesn’t just automatically happen.
So the registration of your DummyComboMotor
class should be as follow:
builder.RegisterType(typeof(DummyComboMotor))
.As(typeof(DummyComboMotor))
.As(typeof(IMotorInterface))
.Keyed("ComboMotor", typeof(IMotorInterface))
.WithAttributeFiltering();