Search code examples
c#autofac

Autofac reporting circular dependency only when using keyed attribute


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>();
    }
}

Solution

  • 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();