DI031
Shared Implementation Registered Under Several Service Types
One implementation type registered under two or more different service types with the same singleton or scoped lifetime, as plain type registrations on the same service-collection flow.
Info Default severity · Code fix: No
Guardrails
When DI031 stays silent
Transient registrations are exempt — a fresh instance per resolution is the contract, so there is no shared instance to lose. Registrations with different lifetimes, keyed registrations, factory registrations, pre-built instances, and registrations on different service-collection flows are all left alone, as is the same service type registered twice (that is DI012's duplicate registration). Registrations guarded by an if, switch, loop, or try never both run, so no two-instance claim is made, and neither do registrations in different executable bodies. Grouping is by constructed type, so GenericStore<int> and GenericStore<string> are distinct, and a RemoveAll or Replace that runs after the registration it removes withdraws the claim (a removal earlier in the method does not). Known false negatives: an open-generic registration paired with a closed one, and a fluent chain that removes a service type and then re-registers it in the same expression. Reported at Info: separate instances are occasionally deliberate, and the forwarding fix is a design decision.