/di

Boost.DI: C++14 Dependency Injection Library

Primary LanguageC++

Boost Licence Version Build Status Build Status Coveralls Github Issues


#Experimental Boost.DI

Your C++14 header only Dependency Injection library with no dependencies (Try it online!)

+---------------------------------------------------+
|$CXX -std=c++14 -fno-exceptions -O2 hello_world.cpp|
|#Compiles in 0.4s!                                 |
+-----------------------------+---------------------+
                              |
                              \
                                  #include <boost/di.hpp> +-----------+
 +-----------------------------+                                      |
 |                             |  namespace di = boost::di;     +-----+--------------------------------+
 |                             +-+                              |One header (3k lines, no dependencies)|
 |  +-----------------------+    +struct uniform {              +--------------------------------------+
 |  |Automatic conversion   |       bool &b;
 |  |between std::shared_ptr+------+boost::shared_ptr<interface> sp;
 |  |and boost::shared_ptr  |     };
 |  +-----------------------+
 |                             +-+class direct {
 |                          +--+   public:                                 +---------------------------+
 |                          |       direct(const uniform &uniform          |ASM x86-64 == `make_unique`|
 |               +----------+            , std::shared_ptr<interface> sp)  +---------------------------+
 |               |                    : uniform_(uniform)                  |push   %rax                |
 |               |                  , sp_(sp)                              |mov    $0x8,%edi           |
 |               |                  {}                                     |callq  0x4007b0 <_Znwm@plt>|
 |               |                                                         |movq   $0x400a10,(%rax)    |
 | +-------------+----------+       const uniform &uniform_;               |mov    $0x8,%esi           |
 | |Inject  dependencies    |       std::shared_ptr<interface> sp_;        |mov    %rax,%rdi           |
 | |using T{...} or T(...)  |     };                                       |callq  0x400960 <_ZdlPvm>  |
 +-+without REFLECTION or   |                                +-------------+mov    $0x1,%eax           |
   |any changes/registration+-----+class hello_world {       |             |pop    %rdx                |
   |in the code!            |      public:                   +             |retq                       |
   +------------------------+       hello_world(std::unique_ptr<direct> d  +-------------------------+-+
                                   +--------+ , interface &ref                                       |
                                   |          , int i)+-------------------------------------------+  +-+
                                   |  : i_(i) {                                                   |    |
                                   |  assert(false == d->uniform_.b);                             |    |
                     +-------------+  assert(d->sp_.get() == d->uniform_.sp.get());               |    |
                     |                assert(&ref == d->sp_.get());     +                         |    |
    +----------------+---------+    }                         +         |                         |    |
    |Deduce scope based on     |                              |         |                         |    |
    |constructor parameter type|    auto run() const {        +---------+ +--------------------+  |    |
    |T -> unique               |      return i_ == 42;                  +-+The same shared_ptr,|  |    |
    |T& -> singleton           |    }                                     |reference provided  |  |    |
    |shared_ptr -> singleton   |                                          +--------------------+  |    |
    |unique_ptr |> unique      |   private:                                                       |    |
    +--------------------------+    int i_ = 0;                                                +--+    |
                                  };                                                           |       |
                                                                                               |       |
                                  int main() {                          +----------------------+--+    |
                                    auto runtime_value = false;         |ASM x86-64 == 'return 42'|    |
                                                                        +-------------------------+    |
                    +-------------+ auto module = [&] {                 |mov $0x2a,%eax           |    |
            +-------+-----------+     return di::make_injector(         |retq                     |    |
            |Split configuration|       di::bind<>().to(runtime_value)  +----+--------------------+    |
            |into modules       |     );                                     |                         |
            +-------+-----------+   };                                       |                         |
                    |         +----------------------------------------------+                         |
                    |         |     auto injector = di::make_injector(                                 |
                    |         |       di::bind<interface>().to<implementation>()+----------------------+
                    |         +---+ , di::bind<>().to(42)
                    +--------------+, module()                                     +---------------------+
                                    );                                  +----------+Compile time creation|
                                                                        +          |guarantee!           |
                                    auto object = injector.create<hello_world>();  +---------------------+
                                    assert(object.run());  +
                                  }                        |
                                                           |  +----------------------------------------+
                                                           +--+Short compile time error messages!      |
                                                              |For example:                            |
                                                              |`abstract_type<interface>::is_not_bound`|
                                                              +----------------------------------------+


Disclaimer Boost.DI is not an official Boost library.