Dependency Injection in C++: A Simple Guide for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to Dependency Injection in C++



When you first start learning C++, you write simple programs where classes create their dependencies directly. For example, a Car class creates an Engine object itself. This works for small projects, but as the code grows, this approach leads to serious problems: the code becomes tightly coupled, difficult to test, and hard to modify.



Dependency Injection (DI) is a design pattern where an object receives its dependencies from the outside, rather than creating them itself. This is one of the key principles of SOLID, specifically the Dependency Inversion Principle.



In this article, we will break down what Dependency Injection in C++ is, why it is needed, and how to apply it in practice. You will see how this pattern makes code flexible, testable, and maintainable.



Why It's Bad Without DI: The Problem of Tight Coupling



Imagine you are writing a smart home management system. There is a SmartLight class that controls a light bulb. In a naive implementation, it creates a Bulb object itself:



#include <iostream>#include <string>

class Bulb {public: void turnOn() { std::cout << "Bulb turned on"; } void turnOff() { std::cout << "Bulb turned off"; }};

class SmartLight {private: Bulb bulb; // Tight dependencypublic: void activate() { bulb.turnOn(); } void deactivate() { bulb.turnOff(); }};

int main() { SmartLight light; light.activate(); return 0;}


What are the problems here?



  • Tight coupling: SmartLight is inseparably tied to Bulb. If you want to use a different bulb (e.g., a smart LED or Phillips Hue), you have to change the class code.
  • Testing difficulty: You cannot replace the real bulb with a mock in unit tests.
  • SRP violation: The SmartLight class does two things: manages the bulb and creates it.


This is a classic example of tight coupling, which Dependency Injection aims to eliminate.



What is Dependency Injection in C++: Core Concepts



Dependency Injection (DI) is a technique where an object receives its dependencies (usually via a constructor, setter, or interface) from an external source, rather than creating them itself. The main idea is: "Don't ask for what you need — it will be given to you."



In C++, DI is implemented through:



  • Interfaces (abstract classes): Dependencies are declared via abstract types, not concrete classes.
  • Constructor with parameters: Dependencies are passed through the constructor (the most common method).
  • Setters: Dependencies are set after the object is created.
  • Dependency containers: Special libraries that automatically create and inject dependencies (e.g., boost.di).


Let's rewrite the smart light example using DI:



#include <iostream>#include <memory>

// Abstract interface for a bulbclass IBulb {public: virtual void turnOn() = 0; virtual void turnOff() = 0; virtual ~IBulb() = default;};

// Concrete implementation: regular bulbclass Bulb : public IBulb {public: void turnOn() override { std::cout << "Bulb turned on"; } void turnOff() override { std::cout << "Bulb turned off"; }};

// Another implementation: LED bulbclass LedBulb : public IBulb {public: void turnOn() override { std::cout << "LED bulb turned on"; } void turnOff() override {

Blogs

Book Recommendations