Why it matters
The default DI container cannot resolve circular constructor graphs and will fail at runtime when the service is activated.
If two people each wait for the other to hand over the key first, the door never opens.
DI017
High-confidence activation cycles such as A -> B -> A, including longer transitive loops through constructors, explicit GetRequiredService / GetRequiredKeyedService factory calls, ActivatorUtilities factory construction, keyed-service inheritance, open-generic registrations, exact closed registrations that override open-generic fallbacks, and registered IEnumerable<T> elements. It analyzes only reachable service-registration flows and mirrors the default container's constructor-set rule: equivalent reordered greedy constructors expose the same cycle, while a greediest constructor whose resolved service identifiers (type plus key) are not a superset of every other resolvable constructor stays silent as ambiguous.
Why it matters
The default DI container cannot resolve circular constructor graphs and will fail at runtime when the service is activated.
If two people each wait for the other to hand over the key first, the door never opens.
Install
dotnet add package DependencyInjection.Lifetime.Analyzers --version 3.7.8
README problem example
services.AddScoped<IOrderService, OrderService>();
services.AddScoped<IPaymentService, PaymentService>();
public sealed class OrderService : IOrderService
{
public OrderService(IPaymentService payment) { }
}
public sealed class PaymentService : IPaymentService
{
public PaymentService(IOrderService order) { }
}
Code fix
Repo sample extraction
Sample app circular dependency
public class BadOrderService : IOrderService
{
public BadOrderService(IPaymentService payment) { }
}
Sample app safe pattern
public class GoodOrderService : IOrderService { }
Related guides
More documentation
Nearby diagnostics