### Hello World Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md A basic 'Hello World' example to get started with Boost.DI. ```cpp #include namespace di = boost::di; struct hello { virtual ~hello() = default; virtual const char* operator()() const { return "Hello World"; } }; int main() { auto injector = di::make_injector(); auto hello_ = injector.create(); return 0; } ``` -------------------------------- ### Run Constructor Injection Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This is a general example for running constructor injection, likely demonstrating various scenarios or a basic setup. ```cpp #include #include namespace di = boost::di; struct A {}; struct B { B(A a) {} }; int main() { auto injector = di::make_injector(); injector.create(); } ``` -------------------------------- ### Modules Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows how to organize bindings into modules. ```cpp #include #include namespace di = boost::di; struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { foo(bar& b) {} }; struct module : di::module { auto configure() const { return make_registry([ di::bind().to() ]); } }; int main() { auto injector = di::make_injector(); injector.create(); return 0; } ``` -------------------------------- ### Basic Bindings Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates how to create bindings for types in Boost.DI. ```cpp #include #include namespace di = boost::di; struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { 상관없어(const bar& b) {} }; int main() { auto injector = di::make_injector([ di::bind().to() ]); injector.create(); return 0; } ``` -------------------------------- ### Heap Provider Test Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md A C++ example demonstrating the usage of the heap provider, likely for testing purposes. It shows how to include and potentially use the heap provider. ```cpp #include ``` -------------------------------- ### Annotations Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates the use of annotations for distinguishing dependencies. ```cpp #include #include namespace di = boost::di; struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { foo(const bar& b1, const bar& b2) {} }; struct bar_impl : bar { void bar() const override {} }; int main() { auto injector = di::make_injector([ di::bind().named(di::annotation("1")), di::bind().named(di::annotation("2")) ]); injector.create(); return 0; } ``` -------------------------------- ### Custom Policy Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates how to implement and use custom policies in Boost.DI. ```cpp #include #include namespace di = boost::di; struct bar { bar() { ++c; } static int c; }; int bar::c = 0; struct foo { foo(bar b) {} }; struct my_policy { template struct apply { template struct apply { template struct apply { using type = T; }; }; }; }; int main() { auto injector = di::make_injector([ di::bind().to() ]); injector.create(); return 0; } ``` -------------------------------- ### Multiple Bindings Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Illustrates how to bind multiple implementations to the same interface. ```cpp #include #include namespace di = boost::di; struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { foo(const bar& b) {} }; struct bar1 : bar { void bar() const override {} }; struct bar2 : bar { void bar() const override {} }; int main() { auto injector = di::make_injector([ di::bind(), di::bind().named("2") ]); injector.create(); injector.create(); return 0; } ``` -------------------------------- ### Binding Templates Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates binding template types in Boost.DI. ```cpp #include #include namespace di = boost::di; template struct service { virtual ~service() = default; virtual void run(T) const = 0; }; template struct impl : service { void run(T) const override {} }; struct controller { controller(const service& s) {} }; int main() { auto injector = di::make_injector([ di::bind>().to>() ]); injector.create(); return 0; } ``` -------------------------------- ### Multiple Interfaces Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows how to handle multiple interfaces for a single implementation. ```cpp #include #include namespace di = boost::di; struct bar1 { virtual ~bar1() = default; virtual void bar1() const = 0; }; struct bar2 { virtual ~bar2() = default; virtual void bar2() const = 0; }; struct foo { foo(bar1& b1, bar2& b2) {} }; struct service : bar1, bar2 { void bar1() const override {} void bar2() const override {} }; int main() { auto injector = di::make_injector([ di::bind(), di::bind() ]); injector.create(); return 0; } ``` -------------------------------- ### Basic Annotations Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md A fundamental example illustrating the use of annotations in Boost.DI for constructor injection. This snippet sets up a basic scenario where annotations are applied to differentiate parameters. ```cpp #include namespace di = boost::di; struct T { BOOST_DI_INJECT(T, (named = value) int value); }; int main() { auto injector = di::make_injector(); auto t = injector.create(); return 0; } ``` -------------------------------- ### Dynamic Bindings Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Illustrates dynamic binding capabilities in Boost.DI. ```cpp #include #include namespace di = boost::di; struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { 상관없어(const bar& b) {} }; int main() { auto injector = di::make_injector([ di::bind().to([](const auto&...) { return std::make_unique(); }) ]); injector.create(); return 0; } ``` -------------------------------- ### Polymorphism Inheritance Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates polymorphism using inheritance with Boost.DI. ```cpp #include #include namespace di = boost::di; struct i_base { virtual ~i_base() = default; virtual void run() const = 0; }; struct base : i_base { void run() const override {} }; struct derived : base { void run() const override {} }; struct controller { controller(const i_base& b) {} }; int main() { auto injector = di::make_injector([ di::bind() ]); injector.create(); return 0; } ``` -------------------------------- ### Custom Provider Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows how to create and use custom providers for dependency creation. ```cpp #include #include namespace di = boost::di; struct bar { bar(int) {} }; struct foo { foo(bar b) {} }; struct my_provider { template T operator()(const di::injector&, Ts...) const { return T(42); } }; int main() { auto injector = di::make_injector([ di::bind().provider(my_provider{}).template to() ]); injector.create(); return 0; } ``` -------------------------------- ### Assisted Injection Extension Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This example demonstrates the Assisted Injection extension in Boost.DI. Assisted injection allows for more complex dependency injection scenarios where parameters might need to be resolved at runtime. ```cpp #include namespace di = boost::di; struct T { BOOST_DI_INJECT(T, (int value)); }; int main() { auto injector = di::make_injector(); auto t = injector.create(); return 0; } ``` -------------------------------- ### Is Creatable Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates how to check if a type is creatable by the injector. ```cpp #include #include namespace di = boost::di; struct bar {}; struct foo { foo(bar) {} }; int main() { auto injector = di::make_injector(); std::cout << std::boolalpha; std::cout << injector.is_creatable(); std::cout << injector.is_creatable(); return 0; } ``` -------------------------------- ### Forward Bindings Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows how to use forward bindings for types that are not yet defined. ```cpp #include #include namespace di = boost::di; struct bar; struct foo { foo(bar& b) {} }; int main() { auto injector = di::make_injector([ di::bind().forward() ]); injector.create(); return 0; } ``` -------------------------------- ### Custom Provider for Controlled Object Allocation Source: https://context7.com/boost-ext/di/llms.txt Implement the `get()` interface for a custom provider to control how objects are allocated (e.g., stack vs. heap, pooling). Pass the provider via a custom config. This example logs every object allocation. ```cpp #include #include namespace di = boost::di; // Custom provider that prints every allocation struct logging_provider { template struct is_creatable { static constexpr auto value = true; }; template auto get(const TInit& init, const TMemory& mem, TArgs&&... args) const { std::printf("Creating: %s\n", typeid(T).name()); return di::providers::stack_over_heap{}.get( init, mem, std::forward(args)... ); } }; struct logging_config : di::config { template static auto provider(const TInjector&) noexcept { return logging_provider{}; } }; struct widget { int x; }; struct window { explicit window(widget w) { (void)w; } }; int main() { const auto injector = di::make_injector( di::bind.to(42) ); injector.create(); // Output: // Creating: 6widget // Creating: 6window } ``` -------------------------------- ### Polymorphism Concepts Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates polymorphism using C++ concepts with Boost.DI. ```cpp #include #include #include namespace di = boost::di; template concept MyConcept = requires(T t) { t.run(); }; template struct service { virtual ~service() = default; virtual void run(T) const = 0; }; template struct impl : service { void run(T) const override {} }; struct controller { controller(const service& s) {} }; int main() { auto injector = di::make_injector([ di::bind>().to>() ]); injector.create(); return 0; } ``` -------------------------------- ### Eager Singletons Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates how to create eager singletons that are instantiated upon injector creation. ```cpp #include #include namespace di = boost::di; struct bar { bar() { ++c; } static int c; }; int bar::c = 0; int main() { auto injector = di::make_injector([ di::bind().in(di::singleton) ]); std::cout << bar::c; return 0; } ``` -------------------------------- ### Automatic Injection Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows how Boost.DI can automatically inject dependencies. ```cpp #include #include namespace di = boost::di; struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { foo(bar& b) {} }; int main() { auto injector = di::make_injector([ di::bind().to() ]); injector.create(); return 0; } ``` -------------------------------- ### Modules (hpp/cpp) Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Illustrates using separate hpp and cpp files for Boost.DI modules. ```cpp // Example for modules.hpp #include namespace di = boost::di; struct bar; struct foo; struct module : di::module { auto configure() const { return make_registry([ di::bind().to() ]); } }; // Example for modules.cpp #include "modules.hpp" struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { foo(bar& b) {} }; int main() { auto injector = di::make_injector(); injector.create(); return 0; } ``` -------------------------------- ### Pool Provider Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates the use of a pool provider for efficient object management. ```cpp #include #include namespace di = boost::di; struct bar { bar() { ++c; } static int c; }; int bar::c = 0; struct foo { foo(bar b) {} }; int main() { auto injector = di::make_injector([ di::bind().in(di::singleton).provider(di::pool_provider) ]); injector.create(); return 0; } ``` -------------------------------- ### Expose Annotated Types via Module Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This example demonstrates how to expose annotated types using modules in Boost.DI. It shows the setup required for exposing types with specific names or annotations. ```cpp #include #include struct MyService {}; int main() { auto module = di::make_injector( [](auto& injector) { injector.template install(); } ); auto service = module.create(); return 0; } ``` -------------------------------- ### Print Types Policy Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This snippet is part of an example demonstrating how to use policies to print information about the types being created by the injector. It's typically used for debugging or understanding the dependency resolution process. ```cpp #include namespace di = boost::di; struct print_types { template void operator()(const T&) { std::cout << " " << boost::core::demangle(typeid(T).name()) << std::endl; } }; int main() { auto injector = di::make_injector(); injector.create>(); return 0; } ``` -------------------------------- ### Basic Main Function Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md A minimal main function to start a Boost.DI application. ```cpp int main() {} ``` -------------------------------- ### Custom Scope Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Illustrates how to define and use custom scopes in Boost.DI. ```cpp #include #include namespace di = boost::di; struct scope : di::extension_local_scope {}; struct bar { bar() { ++c; } static int c; }; int bar::c = 0; struct foo { foo(di::extension b) {} }; int main() { auto injector = di::make_injector([ di::bind().in(di::extension) ]); injector.create(); return 0; } ``` -------------------------------- ### Constructor Injection with Default Values Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Demonstrates constructor injection where default values are provided for parameters. This example is part of the general constructor injection examples. ```cpp #include namespace di = boost::di; struct A {}; struct B { B(A a = {}) {} }; int main() { auto injector = di::make_injector(); injector.create(); } ``` -------------------------------- ### Binding To Constructor Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Illustrates binding a type directly to its constructor. ```cpp #include #include namespace di = boost::di; struct bar { bar(int) {} }; struct foo { foo(bar b) {} }; int main() { auto injector = di::make_injector([ di::bind().to() ]); injector.create(); return 0; } ``` -------------------------------- ### Polymorphism Function Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Demonstrates polymorphism using std::function with Boost.DI. ```cpp #include #include #include namespace di = boost::di; struct controller { controller(std::function func) {} }; int main() { auto injector = di::make_injector([ di::bind>().to([](const auto&...) { return std::function([]() {}); }) ]); injector.create(); return 0; } ``` -------------------------------- ### Configuring Default Provider Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Example of configuring the default provider globally via BOOST_DI_CFG. This sets the provider used for object creation. ```cpp struct config : di::config { template static auto provider(const TInjector&) noexcept { return providers::stack_over_heap{}; } }; ``` -------------------------------- ### Deduce Scope Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows how Boost.DI can deduce the scope of a dependency. ```cpp #include #include namespace di = boost::di; struct bar { bar() { ++c; } static int c; }; int bar::c = 0; struct foo { foo(bar b1, bar b2) {} }; int main() { auto injector = di::make_injector(); injector.create(); std::cout << bar::c; return 0; } ``` -------------------------------- ### DI vs. No DI Coffee Maker Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/index.md Compares a coffee maker class without DI to one with DI, highlighting how dependencies are managed. The DI version injects dependencies via the constructor. ```cpp No Dependency injection | Dependency Injection ----------------------------------------|------------------------------------------- class coffee_maker { public: void brew() { heater->on(); pump->pump(); clog << "coffee"! << endl; heater->off(); } private: shared_ptr heater = make_shared(); unique_ptr pump = make_unique(heater); }; ``` ```cpp class coffee_maker { public: coffee_maker(const shared_ptr& heater , unique_ptr pump) : heater(heater), pump(move(pump)) { } void brew() { heater->on(); pump->pump(); clog << "coffee!" << endl; heater->off(); } private: shared_ptr heater; unique_ptr pump; }; ``` -------------------------------- ### ASM x86-64 Example Source: https://github.com/boost-ext/di/blob/cpp14/README.md Assembly output for a simple function, likely related to object creation or management within the DI framework. ```asm xor eax, eax retq ``` -------------------------------- ### Polymorphism Variant Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows polymorphism using std::variant with Boost.DI. ```cpp #include #include #include namespace di = boost::di; struct service1 { void run() const {} }; struct service2 { void run() const {} }; struct controller { controller(std::variant s) {} }; int main() { auto injector = di::make_injector([ di::bind>().to() ]); injector.create(); return 0; } ``` -------------------------------- ### Binding Non-owning Pointer Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows how to bind a non-owning pointer to a type. ```cpp #include #include namespace di = boost::di; struct bar { virtual ~bar() = default; virtual void bar() const = 0; }; struct foo { foo(const bar* b) {} }; int main() { bar b; auto injector = di::make_injector([ di::bind().to(&b) ]); injector.create(); return 0; } ``` -------------------------------- ### Define Interface and Implementations Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Define an interface (`iview`) and its implementations (`gui_view`, `text_view`). `gui_view` requires constructor parameters, while `text_view` does not. This setup is used to demonstrate Boost.DI's binding capabilities. ```cpp class iview { public: virtual ~iview() noexcept = default; virtual void update() =0; }; class gui_view: public iview { public: gui_view(std::string title, const renderer&) {} void update() override {} }; class text_view: public iview { public: void update() override {} }; ``` -------------------------------- ### Create Object Graph with boost-ext.di Source: https://github.com/boost-ext/di/blob/cpp14/README.md Example demonstrating how to create an object graph by binding simple types to values. Use this when you need to inject primitive types or simple values into your classes. ```cpp class ctor { public: explicit ctor(int i) : i(i) {} int i; }; struct aggregate { double d; }; class example { public: example(aggregate a, const ctor& c) { assert(87.0 == a.d); assert(42 == c.i); }; }; int main() { const auto injector = di::make_injector( di::bind.to(42), di::bind.to(87.0) ); injector.create(); } ``` -------------------------------- ### Manual Object Tree Creation Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md An example of manually creating an object tree for a simplified Model-View-Controller structure. This approach can become tedious to maintain. ```cpp renderer renderer_; view view_{"", renderer_}; model model_; controller controller_{model_, view_}; user user_; app app_{controller_, user_}; ``` -------------------------------- ### DI in C++ Constructor Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/index.md Demonstrates Dependency Injection using a C++ constructor. The Button class takes its name and position as constructor arguments, illustrating DI. ```cpp class Button { public: Button(const std::string& name, Position position); // Dependency Injection! }; ``` -------------------------------- ### Scope Deduction Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Demonstrates how Boost.DI deduces scopes based on constructor parameter types like references, shared_ptr, and unique_ptr. ```cpp class scopes_deduction { scopes_deduction(const int& /*singleton scope*/, std::shared_ptr /*singleton scope*/, std::unique_ptr /*unique scope*/, int /*unique scope*/) { } }; di::make_injector().create(); // scopes will be deduced based on constructor parameter types ``` -------------------------------- ### Constructor Injection with Ambiguous Constructors via di::inject Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This example showcases handling ambiguous constructors using `di::inject`. ```cpp #include namespace di = boost::di; struct A {}; struct B { B(A a) {} B(A a, int) {} }; int main() { auto injector = di::make_injector(); injector.create(); } ``` -------------------------------- ### UML Dumper Extension Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/index.md This C++ code demonstrates the usage of the UML Dumper extension for Boost.DI, which helps in understanding object hierarchies. ```cpp #include namespace di = boost::di; struct bar {}; struct foo { foo(bar &) {} }; int main() { auto module = [] {}; di::injector injector{module}; injector.create(); return 0; } ``` -------------------------------- ### Include Boost.DI and Define Aliases and Interfaces Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This snippet includes the necessary Boost.DI header, defines a namespace alias 'di', and sets up basic interfaces and implementation classes used in subsequent examples. ```cpp #include namespace di = boost::di; struct i1 { virtual ~i1() = default; virtual void dummy1() = 0; }; struct i2 { virtual ~i2() = default; virtual void dummy2() = 0; }; struct impl1 : i1 { void dummy1() override { } }; struct impl2 : i2 { void dummy2() override { } }; struct impl : i1, i2 { void dummy1() override { } void dummy2() override { } }; ``` -------------------------------- ### Define Custom Policies Configuration Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Example of how to define a custom configuration for policies. This involves creating a struct that inherits from `di::config` and overrides the `policies` static method to return a callable list of policies. ```cpp #include namespace di = boost::di; struct config : di::config { template static auto policies(const TInjector&) noexcept { return di::make_policies(...); } }; // policy template void operator()(const T&); ``` -------------------------------- ### ASM x86-64 Example (make_unique) Source: https://github.com/boost-ext/di/blob/cpp14/README.md Assembly output for `make_unique` related operations, showing memory allocation and object construction. ```asm push %rbx mov %rdi,%rbx mov $0x8,%edi callq 0x4008e0 <_Znwm@plt> movq $0x400c78,(%rax) mov %rax,(%rbx) mov %rbx,%rax pop %rbx retq ``` -------------------------------- ### Ambiguous Constructors Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Shows a scenario with a class having multiple constructors with the same number of parameters, leading to ambiguity that Boost.DI flags at compile time. ```cpp class model { public: model(int size, double precision) { } model(int rows, int cols) { } }; ``` -------------------------------- ### Bind Interfaces with boost-ext.di Source: https://github.com/boost-ext/di/blob/cpp14/README.md Example showing how to bind an interface to its implementation using `std::shared_ptr`. Use this for dependency injection of polymorphic types. ```cpp struct interface { virtual ~interface() noexcept = default; virtual int get() const = 0; }; class implementation : public interface { public: int get() const override { return 42; } }; struct example { example(std::shared_ptr i) { assert(42 == i->get()); } }; int main() { const auto injector = di::make_injector( di::bind.to() ); injector.create>(); } ``` -------------------------------- ### boundable_type_is_neither_a_dependency_nor_an_injector Error Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Demonstrates the error when a type `T` is neither a dependency nor an injector, failing the 'boundable' concept. ```cpp #include namespace di = boost::di; struct T {}; int main() { auto injector = di::make_injector(); injector.create(); return 0; } ``` -------------------------------- ### configurable_requires_callable_and_providable Error Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Illustrates the error when a configuration type `TConfig` does not meet the 'configurable' concept requirements (providable provider and callable policies). ```cpp #include namespace di = boost::di; struct TConfig {}; int main() { auto injector = di::make_injector( di::bind>().to() ); return 0; } ``` -------------------------------- ### Bind Concepts with Streamable Interface Source: https://github.com/boost-ext/di/blob/cpp14/README.md Shows how to bind concepts using a `Streamable` interface for exchange and engine streams. This example sets up dependencies for a class that requires streamable objects. ```cpp struct Streamable { template auto requires(T&& t) -> decltype( int( t.read() ), t.write(int) ); }; template class example { public: example(Exchange exchange, Engine engine) : exchange(std::move(exchange)), engine(std::move(engine)) { } private: Exchange exchange; Engine engine; }; int main() { const auto injector = di::make_injector( di::bind.to(), di::bind.to() ); injector.create(); } ``` -------------------------------- ### Expose Multiple Annotated Types via Module Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This example illustrates exposing multiple annotated types using modules. It showcases how to manage and expose several distinct types with their respective annotations. ```cpp #include #include struct MyService1 {}; struct MyService2 {}; int main() { auto module = di::make_injector( [](auto& injector) { injector.template install(); } ); auto service1 = module.create(); auto service2 = module.create(); return 0; } ``` -------------------------------- ### Binding Concepts/Templates Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Shows how Boost.DI can inject concepts and templates. The example binds a type to a template that uses it, ensuring type safety at compile time. ```cpp template struct example { using type = T; }; struct hello {}; int main() { const auto injector = di::make_injector( di::bind.to() ); auto object = injector.create(); static_assert(std::is_same{}); } ``` -------------------------------- ### Annotated Constructor Injection with Same Names Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This example shows how to handle constructor injection when parameters have the same type and name, using annotations to differentiate them. The `named` annotation is used to assign unique identifiers to each parameter. ```cpp #include namespace di = boost::di; struct T { BOOST_DI_INJECT(T, (named = value) int value, (named = value) int value2); }; int main() { auto injector = di::make_injector(); auto t = injector.create(); return 0; } ``` -------------------------------- ### boundable_type_is_abstract Error Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Demonstrates the error when an abstract type `T` is used, violating the 'boundable' concept. The `BOOST_DI_CFG_DIAGNOSTICS_LEVEL` can be set to 2 to get more information about why the type is abstract. ```cpp #include namespace di = boost::di; struct T {}; int main() { // BOOST_DI_CFG_DIAGNOSTICS_LEVEL = 2; auto injector = di::make_injector(); injector.create(); return 0; } ``` -------------------------------- ### Bind Templates with Custom Error Policy Source: https://github.com/boost-ext/di/blob/cpp14/README.md Demonstrates binding a template with a custom error policy. The example terminates with an exception due to the bound `throw_policy`. ```cpp template class simple_updater { public: void update() const { ErrorPolicy::on("update"); } }; template class example { public: explicit example(const Updater& updater) : updater(updater) { } void update() { updater.update(); } private: const Updater& updater; }; int main() { struct throw_policy { static void on(const std::string& str) { throw std::runtime_error(str); } }; const auto injector = di::make_injector( di::bind.to(), di::bind.to() ); injector.create().update(); // Terminates with an uncaught exception because of our bound error policy } ``` -------------------------------- ### Error: Provider Requires 'get' Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This error indicates that a type intended to be used as a provider is missing the required 'get' method. Ensure that any custom provider implements a 'get' method with the appropriate signature. ```cpp #include namespace di = boost::di; struct MissingGetProvider {}; int main() { auto injector = di::make_injector( di::bind().to(di::provider{}) ); // Error: provider requires get // injector.create(); return 0; } ``` -------------------------------- ### Avoid Passing Dependencies to Create Other Dependencies in C++ Source: https://github.com/boost-ext/di/blob/cpp14/doc/index.md When creating a dependency within an object, it's better to create the dependency beforehand and pass it in. This example shows the 'bad' way of creating a Board inside Model and the 'better' way of passing an IBoard. ```cpp class Model { public: Model(int width, int height) : board(std::make_unique(width, height)) // Bad { } explicit Model(std::unique_ptr board) // Better : board(std::move(board)) { } ... private: std::unique_ptr board; }; ``` -------------------------------- ### Avoid Service Locator Pattern in C++ Source: https://github.com/boost-ext/di/blob/cpp14/doc/index.md Passing a service locator to all constructors creates tight coupling. It's preferable to directly inject required dependencies. This example shows the 'bad' way of using a service locator and the 'better' way of direct injection. ```cpp class Model { public: explicit Model(service_locator& sl) // Bad (ask) : service(sl.resolve>()) { } explicit Model(std::unique_ptr service) // Better (tell) : service(std::move(service)) { } ... private: std::unique_ptr service; }; ``` -------------------------------- ### Run C++ DI Benchmarks Source: https://github.com/boost-ext/di/blob/cpp14/doc/benchmarks.md Navigate to the benchmark directory and execute the make command to run the performance tests. ```shell cd benchmark && make ``` -------------------------------- ### Dynamic Bindings with Boost.DI Source: https://github.com/boost-ext/di/blob/cpp14/doc/FAQ.md Illustrates how to configure dynamic bindings based on runtime conditions. This is useful for selecting implementations, such as choosing between a GUI or text-based view, or setting a default value. ```cpp auto use_gui_view = true/false; auto injector = di::make_injector( di::bind.to([&](const auto& injector) -> iview& { if (use_gui_view) return injector.template create(); else return injector.template create(); }) , di::bind<>.to(42) // renderer device ); ``` -------------------------------- ### Include boost-ext.di Header Source: https://github.com/boost-ext/di/blob/cpp14/README.md Include the main header file for the boost-ext.di library. This is the only file required. ```cpp #include namespace di = boost::di; ``` -------------------------------- ### boundable_type_is_bound_more_than_once Error Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Illustrates the error when a type `T` is bound more than once, violating the 'boundable' concept. ```cpp #include namespace di = boost::di; struct T {}; int main() { auto injector = di::make_injector( di::bind().to() ); injector.create(); return 0; } ``` -------------------------------- ### Clone and Build Boost.DI Tests Source: https://github.com/boost-ext/di/blob/cpp14/doc/overview.md Clone the Boost.DI repository from GitHub and run 'make' to build and execute the tests. ```shell git clone https://github.com/boost-ext/di && cd di && make ``` -------------------------------- ### Polymorphism Type Erasure Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/examples.md Shows polymorphism using type erasure with Boost.DI. ```cpp #include #include #include #include namespace di = boost::di; struct i_service { virtual ~i_service() = default; virtual void run() const = 0; }; struct service : i_service { void run() const override {} }; struct controller { controller(std::function func) {} }; int main() { auto injector = di::make_injector([ di::bind>().to([](const auto&...) { return std::function([]() {}); }) ]); injector.create(); return 0; } ``` -------------------------------- ### Define and Declare Modules in C++ Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Demonstrates how to define and declare modules for dependency injection, separating configuration into different functions. This is useful for organizing complex dependency graphs. ```cpp di::injector model_module() { return di::make_injector( di::bind.named(Rows).to(6) , di::bind.named(Cols).to(8) ); } di::injector app_module(const bool& use_gui_view) { return di::make_injector( di::bind.to([&](const auto& injector) -> iview& { if (use_gui_view) return injector.template create(); else return injector.template create(); }) , di::bind.in(di::unique) // different per request , di::bind.to() // bind many clients , model_module() ); } ``` -------------------------------- ### Download boost/di.hpp Header Source: https://github.com/boost-ext/di/blob/cpp14/doc/overview.md Use wget to download the boost/di.hpp header file from the official repository. ```shell wget https://raw.githubusercontent.com/boost-ext/di/cpp14/include/boost/di.hpp ``` -------------------------------- ### boundable_type_has_disallowed_qualifiers Error Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Illustrates the error when a type `T` has disallowed qualifiers, violating the 'boundable' concept. ```cpp #include namespace di = boost::di; struct T {}; int main() { auto injector = di::make_injector(); injector.create(); return 0; } ``` -------------------------------- ### Cross-Platform Bindings Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Demonstrates how bindings can be configured in a way that is portable across different platforms or build configurations. This often involves conditional compilation or platform-specific configurations. ```cpp #if defined(_WIN32) || defined(_WIN64) #include #else #include #endif #include namespace di = boost::di; struct Service {}; int main() { di::injector injector = di::make_injector( di::bind().in(di::extension::make_linux<>()) ); return 0; } ``` -------------------------------- ### callable_requires_call_operator Error Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Shows the error when a policy `TPolicy` does not have a call operator, violating the 'callable' concept. ```cpp #include namespace di = boost::di; struct TPolicy {}; int main() { auto injector = di::make_injector( di::bind>().to() ); return 0; } ``` -------------------------------- ### Constructible Policy Usage with Logic Operators Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Illustrates how to use the `constructible` policy with logic operators (`!`, `&&`, `||`) for complex constructor parameter constraints. Requires `boost::di::policies::operators` namespace. ```cpp using namespace boost::di::policies::operators; // Example: Allow only int parameters, or parameters that are constructible from int, or parameters that are base of int // auto policy = std::is_same<_, int>{} || std::is_constructible<_, int>{} || std::is_base_of{}; ``` -------------------------------- ### boundable_type_is_not_related_to Error Example Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Shows the error when type `T` is not related to type `U`, failing the 'boundable' concept check. ```cpp #include namespace di = boost::di; struct T {}; struct U {}; int main() { auto injector = di::make_injector(); injector.create(); injector.create(); return 0; } ``` -------------------------------- ### Motivation for Boost.DI Source: https://github.com/boost-ext/di/blob/cpp14/doc/index.md Illustrates the 'wiring mess' that arises from manual dependency management, leading to maintenance issues and code complexity. This scenario highlights the need for a DI solution. ```text * Single Responsibility Principle => * A lot of classes => * Wiring Mess => * Hard to maintain + Lazy programmers (99%) => * Hacks/Workarounds (~~Single Responsibility~~) ``` -------------------------------- ### Core Injector Implementation Details Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md Illustrates the internal structure and `create` method of the `core::injector`. This snippet shows how policies are verified, dependencies are resolved, and types are wrapped for creation. ```cpp struct direct; // T(...) struct uniform; // T{...} template is_braces_constructible; // type T is constructible using T{...} template is_constructible; // Type T is constructible using T(...) template is_injectable; // Type T uses BOOST_DI_INJECT or BOOST_DI_INJECT_TRAITS template // For Example, TBindings = { di::bind.to } struct core::injector : TBindings... { using config = TConfig; using deps = TBindings...; template // For example, T = Interface auto create() const noexcept { TConfig::policies()...; // verify policies using Type = core::binder().resolve(*this); // Type = Implementation return core::wrapper{dependency.create(provider{*this}.get())}; } }; template struct provider { template auto get() const noexcept { using pair = decltype(ctor_traits()); return TConfig::provider().get(TInitialization{}, TCtor...); } const TInjector& injector; }; template struct any_type { template operator T() const { return injector.templte create(); } const TInjector& injector; }; template auto ctor_traits() { if (is_injectable() { return pair{}; // BOOST_DI_INJECT(T, args...) -> T(args...) } for (auto i = BOOST_DI_CFG_CTOR_LIMIT_SIZE; i >= 0; --i) { if (is_constructible...>()) { // ... -> i times return pair...>{}; // T(any_type...) } } for (auto i = BOOST_DI_CFG_CTOR_LIMIT_SIZE; i >= 0; --i) { if (is_braces_constructible...>()) { // ... -> i times return pair...>{}; // T{any_type...} } } return error(...); }; ``` -------------------------------- ### Concept: Providable Type Requirement Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md The 'providable' concept defines the requirements for types that can provide dependencies. It mandates the presence of 'get' and 'is_creatable' methods. ```cpp #include namespace di = boost::di; // Example of a providable type (simplified) struct MyProvider { template T get(Ts...) { // ... implementation ... return T{}; } template bool is_creatable(Ts...) { // ... implementation ... return true; } }; int main() { // A type satisfying the providable concept can be used by di return 0; } ``` -------------------------------- ### Basic Dependency Injection Binding Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Demonstrates how to bind an interface to a concrete implementation and bind a simple type like int. Boost.DI can deduce the type for simple bindings. ```cpp const auto injector = di::make_injector( di::bind.to() , di::bind.to(42) // renderer.device | [Boost].DI can also deduce 'int' type for you -> 'di::bind<>.to(42)' ); ``` -------------------------------- ### Constructor Injection with Ambiguous Constructors via di::ctor_traits Source: https://github.com/boost-ext/di/blob/cpp14/doc/user_guide.md This example shows how to resolve ambiguous constructors for types using `di::ctor_traits`. ```cpp #include namespace di = boost::di; struct A {}; struct B { B(A a) {} B(A a, int) {} }; namespace boost { namespace di { template <> struct ctor_traits { using type = di::inject; }; }} int main() { auto injector = di::make_injector(); injector.create(); } ``` -------------------------------- ### Dynamic Binding with Runtime Choice Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Illustrates how to use a lambda to dynamically choose between different implementations at runtime based on a condition. The injector is passed to the lambda to create dependencies. ```cpp auto use_gui_view = true/false; const auto injector = di::make_injector( di::bind.to([&](const auto& injector) -> iview& { if (use_gui_view) return injector.template create(); else return injector.template create(); }) , di::bind<>.to(42) // renderer device ); ``` -------------------------------- ### Create App Object with Boost.DI Source: https://github.com/boost-ext/di/blob/cpp14/doc/tutorial.md Use `make_injector().create()` to automatically resolve and inject dependencies for an `app` object. Boost.DI handles complex dependency hierarchies and constructor parameter changes without explicit registration. ```cpp auto app_ = make_injector().create(); // It will create an `app` on stack and call its copy constructor ```