Boost C++ Libraries

PrevUpHomeNext
Introduction
Overview
Tutorial
Try It Online!
Benchmarks
User Guide
Examples
Extensions
FAQ
CHANGELOG

Boost Licence Version Build Status Build Status Coveralls Github Issues


Introduction

[Boost::ext].DI
Your C++14 header only Dependency Injection library with no dependencies (Try it online!) GitHub
  Download        Changelog        Tutorial        Examples

What is Dependency Injection?

"Don't call us, we'll call you", Hollywood principle

Dependency Injection (DI) involves passing (injecting) one or more dependencies (or services) to a dependent object (or client) which become part of the client’s state. It is like the Strategy Pattern, except the strategy is set once, at construction. DI enables loosely coupled designs, which are easier to maintain and test.

In short, DI is all about construction!

"Let's make some coffee!"

Coffee Maker

                      No Dependency injection                 | Dependency Injection
                      ----------------------------------------|-------------------------------------------
                      class coffee_maker {                    | class coffee_maker {
                      public:                                 | public:
                          void brew() {                       |   coffee_maker(const shared_ptr<iheater>& heater
                              heater->on();                   |              , unique_ptr<ipump> pump)
                              pump->pump();                   |         : heater(heater), pump(move(pump))
                              clog << "coffee"! << endl;      |     { }
                              heater->off();                  |
                          }                                   |     void brew() {
                                                              |         heater->on();
                      private:                                |         pump->pump();
                          shared_ptr<iheater> heater =        |         clog << "coffee!" << endl;
                              make_shared<electric_heater>(); |         heater->off();
                                                              |     }
                          unique_ptr<ipump> pump =            |
                              make_unique<heat_pump>(heater); | private:
                      };                                      |     shared_ptr<iheater> heater;
                                                              |     unique_ptr<ipump> pump;
                                                              | };

Do I use a Dependency Injection already?

class Button {
 public:
  Button(const std::string& name, Position position); // Dependency Injection!
};

Do I use Dependency Injection correctly?

Common mistakes when using Dependency Injection are:

class Model {
 public:
   Model(int width, int height)
     : board(std::make_unique<Board>(width, height)) // Bad
   { }

   explicit Model(std::unique_ptr<IBoard> board) // Better
     : board(std::move(board))
   { }

   ...

 private:
  std::unique_ptr<IBoard> board;
};
class Model : public Service { // Bad
 public:
   explicit Model(std::unique_ptr<IBoard> board) // Bad
     : Service(std::move(board))
   { }

   void update() {
     Service::do_something_with_board(); // Bad
   }
};

class Model { // Better
 public:
   explicit Model(std::unique_ptr<Service> service) // Better
     : service(std::move(service))
   { }

   void update() {
     service->do_something_with_board(); // Better
   }

 private:
   std::unique_ptr<Service> service;
};
class Model {
 public:
   explicit Model(service_locator& sl) // Bad (ask)
     : service(sl.resolve<unique_ptr<Service>>())
   { }

   explicit Model(std::unique_ptr<Service> service) // Better (tell)
     : service(std::move(service))
   { }

   ...

 private:
   std::unique_ptr<Service> service;
};
class Board {
 public:
   Board(int /*width*/, int /*height*/)  // Bad; Board{2, 3} vs Board{3, 2}?

   Board(width, height) // Better, explicit; Board{width{2}, height{3}};

   ...
};

Do I need a Dependency Injection?

STUPID vs SOLID - "Clean Code" Uncle Bob

SSingleton
TTight Coupling
UUntestability
PPremature Optimization
IIndescriptive Naming
DDuplication

vs

SSingle Responsibility
OOpen-close
LLiskov substitution
IInterface segregation
DDependency inversion

Do I need a DI Framework/Library?

Depending on a project and its scale you may put up with or without a DI library, however, in any project a DI framework may free you from maintaining a following (boilerplate) code...

logger logger_;
renderer renderer_;
view view_{renderer_, logger_};
model model_{logger_};
controller controller_{model_, view_, logger_};
user user_{logger_};
app app_{controller_, user_};

Notice that ORDER in which above dependencies are created is IMPORTANT as well as that ANY change in ANY of the objects constructor will REQUIRE a change in this code!

Manual DI - Wiring Mess (Avoid it by using [Boost].DI)

* Single Responsibility Principle
  =>
    * A lot of classes
    =>
      * Wiring Mess
      =>
        * Hard to maintain + Lazy programmers (99%)
        =>
          * Hacks/Workarounds (~~Single Responsibility~~)

CPP(BTN)

Right now, imagine a project with hundreds or thousands of those dependencies and a critical issue which has to be fixed ASAP. Unfortunately, in order to fix the bug properly a new non-trivial dependency has to be introduced.

Now, imagine that a 'smart' dev figured out that it will be much easier to extend the functionally of already passed object and sneak a workaround/'solution' this way. Such approach will possibly break the single responsibility principle of the changed object but no worries though, it might be refactored later on (meaning: most likely, the workaround will stay unchanged forever and that there are no tests).

If that sounds familiar, take a look into DI library as it helps to solve developer dilemma by taking care of creating all required dependencies whereas dev may focus on fixing and testing the issue.


DI library, not only let you forget about maintaining dependencies creation (See Create Objects Tree), but also can help you with...

Real Life examples?

Why [Boost].DI?

Try it online!

CPP(BTN) CPP(BTN) CPP(BTN)



[Boost].DI design goals

Articles

Videos

[Boost::ext].DI

Dependency Injection In General

Acknowledgements


PrevUpHomeNext