# Dependency inversion principle

> Business logic owns the interfaces it needs; infrastructure implements them. Dependencies point toward policy, not toward details.

Concept · SOLID principles · https://levelcode.org/concepts/dependency-inversion

The **dependency inversion principle** (DIP), the D in SOLID, has two parts:

1. High-level modules should not depend on low-level modules. Both should depend on **abstractions**.
2. Abstractions should not depend on details. Details should depend on abstractions.

"High-level" means policy — business rules like pricing or eligibility. "Low-level" means details — Postgres, an HTTP client, a vendor SDK.

## What gets inverted

Without DIP, source dependencies follow the flow of control: billing calls the database, so billing imports the database package. Billing can't be compiled or tested without Postgres, and replacing Postgres means editing billing.

With DIP, billing **declares** the interface it needs, and the database package implements it:

```go
package billing

type InvoiceStore interface {
	Save(ctx context.Context, inv Invoice) error
}

type Service struct{ store InvoiceStore }

func NewService(store InvoiceStore) *Service { return &Service{store: store} }
```

```go
package postgres // imports billing, not the other way round

func (s *InvoiceStore) Save(ctx context.Context, inv billing.Invoice) error { /* SQL */ }
```

Control still flows from billing to Postgres at runtime, but the **source code dependency** now points from Postgres to billing — inverted. The interface belongs to the high-level module, which is why in Go it lives in the consumer's package, not next to the implementation.

## Dependency injection

DIP describes the direction of dependencies; **dependency injection** is the mechanism for supplying them — passing collaborators in through constructors or parameters instead of creating them inside. In Go, `main` is the composition root: it builds the concrete types and wires them together. Frameworks exist (Wire, Fx), but plain constructors are enough for most services.

## What it buys

- **Testability:** business logic runs against in-memory [fakes](https://levelcode.org/concepts/test-doubles).
- **Replaceability:** swap a payment provider or database by writing a new adapter.
- **Stable core:** the most important code depends on nothing volatile.

It's the foundation of [ports and adapters](https://levelcode.org/concepts/ports-and-adapters) and clean architecture. Don't add an interface for every dependency by reflex, though: inverting a dependency on something stable and pure (the standard library, a math package) only adds indirection. See the [SOLID lesson](https://levelcode.org/roadmaps/software-engineer/solid).
