What is the Dependency Inversion Principle, and how is it different from dependency injection?

SOLID & Design Patterns SOLID Advanced 3–5 Yrs5+ Yrs Architecture 1 min read

Quick Answer

The Dependency Inversion Principle says: high-level modules should not depend on low-level modules — both should depend on abstractions; and abstractions should not depend on details. Dependency injection is one technique for achieving it (supply the concrete implementation from outside). An IoC container is a tool that automates the injection.

Dependency Inversion is about the direction of dependencies: your high-level business code and your low-level details like the database should both depend on an abstraction, and that abstraction should be owned by the high-level side. So instead of OrderService creating a SqlOrderRepository, it depends on IOrderRepository, and the SQL implementation implements that interface. Dependency injection is just the practical way to make that happen — you inject the concrete type through the constructor instead of newing it. And the IoC container is the tool that wires it all up. People use the terms interchangeably but the principle, the technique and the tool are three different things.

Without DIP, OrderService (high-level policy) news up SqlOrderRepository (low-level detail). The dependency arrow points from policy to detail, so a database change ripples up.

With DIP, you introduce IOrderRepository. OrderService depends on it; SqlOrderRepository implements it. Both now point at the abstraction, and — crucially — the abstraction is owned by the high-level module, not the data layer. The dependency is “inverted”.

The three terms, precisely:

  • DIP — a design principle about which way dependencies point.
  • DI — a technique: pass dependencies in (constructor injection) rather than creating them.
  • IoC container — infrastructure that resolves and injects them (Microsoft.Extensions.DependencyInjection, Autofac).