skipnothing/.NET Platform

DI Anti-Patterns

A class takes one constructor parameter, `IServiceProvider`, and compiles without complaint. Nothing in its signature admits it needs an email sender, so when that registration goes missing the failure lands on a customer's order, not your build.

  • A constructor that compiles clean can still hide every collaborator the class uses; one IServiceProvider parameter is the tell.
  • Put a per-request service inside a forever one and it freezes at request one, with no error until validation runs.
  • One BuildServiceProvider call in startup quietly mints a second copy of every singleton you registered.
BUILDS ON
01

Service Locator: The Hidden Dependency

OrderService declares one constructor parameter: IServiceProvider provider. Inside its PlaceOrder method it calls provider.GetRequiredService<IEmailSender>() and uses the result. The code compiles, runs in your tests, and reads as ordinary dependency injection. It is not.

Pulling a dependency out of the provider by hand, instead of declaring it in the constructor, is the service locator pattern. The cost hides in plain sight: read the constructor and the class looks like it needs nothing but a provider. The one collaborator it actually depends on, IEmailSender, appears only deep inside a method body. A caller reading the public signature cannot see it. The compiler, which would refuse to build a constructor whose IEmailSender argument has no registration, never gets the chance, because there is no such argument to check.

So the failure moves. Forget to register IEmailSender and constructor injection fails loudly at startup, naming the gap. Service locator sails through the build and throws InvalidOperationException the first time a real order reaches that line, in production, on a Tuesday. The fix is to delete the provider parameter and put IEmailSender sender back in the constructor, where the class can be read and checked.

TWO CONSTRUCTORS, ONE HIDDEN NEED

Keep going, sign up to unlock the rest

3 more parts in this topic, plus 25+ more topics in .NET Platform.

Sign up, it's freeSee the full .NET Platform
Dependency Injection0/6#16 Keyed Services
#18 The Configuration System