Why it matters
registration intent becomes unclear and behaviour differs from what readers expect.
Writing your name on the same seat twice does not get you two seats; one note just replaces the other.
DI012
- `TryAdd*` calls after an `Add*` already registered that service.
Why it matters
registration intent becomes unclear and behaviour differs from what readers expect.
Writing your name on the same seat twice does not get you two seats; one note just replaces the other.
Install
dotnet add package DependencyInjection.Lifetime.Analyzers --version 2.2.2
README problem example
services.AddSingleton<IMyService, ServiceA>();
services.TryAddSingleton<IMyService, ServiceB>(); // ignored
services.AddSingleton<IMyService, ServiceA>();
services.AddSingleton<IMyService, ServiceB>(); // overrides A
README better pattern
Repo sample extraction
Sample app warning case
// ⚠️ BAD: TryAdd will be ignored because ServiceA is already registered
services.AddSingleton<IService, ServiceA>();
services.TryAddSingleton<IService, ServiceB>(); // Diagnostic here
// ⚠️ BAD: Multiple Add calls (Duplicate Registration)
// The second registration overrides the first for single resolution
services.AddScoped<ServiceA>();
services.AddScoped<ServiceA>(); // Diagnostic here
}
}
Sample app duplicate-registration case
// ⚠️ BAD: Multiple Add calls (Duplicate Registration)
// The second registration overrides the first for single resolution
services.AddScoped<ServiceA>();
services.AddScoped<ServiceA>(); // Diagnostic here
}
}
Related guides
More documentation