Thursday, November 6, 2025
Let's Stop Creating Interfaces Just in Case

In the .NET world, we have all been told at some point:
Abstract everything behind an interface.
The result:
IOrderService, IEmailService, IPaymentService… and dozens of useless files. 😅▸ The problem
Often, each interface has a single implementation. So we end up doing this 👇
public interface IOrderService { void PlaceOrder(); }
public class OrderService : IOrderService { ... }
➡️ And we believe we have “decoupled” our code. In reality, we just duplicated the complexity.
▸ Why it's an anti-pattern
An interface with no alternative ≠ abstraction. You gained nothing, just noise.
Tests don't need interfaces. You can test a concrete class, inject a
Func<>, or derive a type to substitute the behavior.Interfaces don't remove coupling. You are simply coupled… to your contract.
DI (Dependency Injection) does NOT require interfaces. The Microsoft container knows how to inject concrete classes.
▸ When an interface makes sense
When you have several implementations (e.g. SendGrid / SES / SMTP).
When you define a clear boundary between modules or domains.
When you want to simplify a public API.
▸ The takeaway
Creating an interface just in case means paying complexity debt right now… for a hypothetical scenario that may never happen.
Abstract everything, and you're left with a bunch of nothing.Derek Comartin
▸ What about you?
Are you in the 🔥 “one interface per service” camp, or more the 🧠 “interfaces when they're useful” camp?
Let me know in the comments 👇
Does this resonate with your team?
Let's talk about how Atypical Consulting can help you move forward.
Contact me