What does "dependency inversion" (inversion) mean?
"Dependency inversion" within the Inversion of Control (IoC) principle means that control over dependencies and the order of execution no longer belongs to the object or module that uses them - this control is "flipped" and handed over to an external system (for example, a framework, a container, or infrastructure code).
What exactly gets flipped
Previously (in the traditional approach) the dependency order looked like this:
A high-level module depends on a low-level one, which depends on specific implementations.
After the "inversion":
Both the high and low levels depend on abstractions, not on each other.
In other words, the dependency is inverted: instead of the "high-level code" dictating which specific implementations to use, an external mechanism now decides this, injecting the needed dependencies.
Example without dependency inversion
class FileLogger:
def log(self, message):
print(f"Log: {message}")
class UserService:
def __init__(self):
self.logger = FileLogger() # concrete dependency
def create_user(self, name):
self.logger.log(f"User created: {name}")UserService depends directly on FileLogger. To change the logger, the code has to be rewritten. Here the high-level module depends on the low-level one.
Example with dependency inversion
class Logger:
def log(self, message):
pass
class FileLogger(Logger):
def log(self, message):
print(f"Log: {message}")
class UserService:
def __init__(self, logger: Logger):
self.logger = logger # dependency on an abstraction
def create_user(self, name):
self.logger.log(f"User created: {name}")Now UserService depends on the Logger interface, not on the concrete FileLogger.
The logger implementation can be replaced by external code or a dependency container.
Control over creating FileLogger is inverted: it is not UserService that decides, but the framework or the calling code.
What the "inversion" means
- Before: the code creates and manages its own dependencies (tight coupling).
- After: dependencies are injected from outside (loose coupling).
- "Inversion" is a transfer of responsibility: from the module to an external container or abstraction.
Connection to SOLID
Dependency inversion is the basis of the Dependency Inversion Principle (DIP) from SOLID:
High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.
Summary: "Dependency inversion" is an architectural technique in which the management of dependencies changes direction: instead of a module directly creating and controlling its dependencies, it depends on abstractions, and specific implementations are injected from outside. This creates a flexible, testable, and easily extensible system.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.