boost-ext/di

repository·cpp14·Indexed 22 days ago

https://github.com/boost-ext/di

A header-only, zero-dependency Dependency Injection library for C++14 that enables developers to manage object lifecycles and dependencies through compile-time injection, supporting interfaces, templates, and concepts.

Tokens
40.3K
Snippets
134
Records
216
Agent score
76%

What's inside boost-ext-di

  1. Overview of reveal.js

    cpp14

    reveal.js is a framework for creating HTML-based presentations. It supports advanced features such as:

    • Nested slides: Create hierarchical slide structures.
    • Markdown contents: Write slide content using Markdown syntax.
    • PDF export: Export presentations to PDF format.
    • Speaker notes: Include notes for the presenter.
    • JavaScript API: Programmatically control and interact with your presentation.

    While it is optimized for modern browsers, it includes fallbacks to ensure compatibility across different environments.

  2. Overview of [Boost.DI]

    cpp14
    [Boost.DI] is a header-only Dependency Injection library for C++14. It is designed to be used without any external dependencies. It provides a way to manage object lifetimes and dependencies in C++ applications through a compile-time dependency injection framework.
  3. Why use a DI Framework like [Boost].DI?

    cpp14

    While manual Dependency Injection is possible, it often leads to a 'Wiring Mess' where the order of object creation must be manually managed and any change to a constructor requires updating the entire creation chain.

    Using a DI framework like [Boost].DI provides several benefits:

    • Reduces Boilerplate: Automates the creation of complex object trees.
    • Testing: Simplifies testing through features like the Mocks Provider.
    • Serialization: Supports object serialization.
    • Visualization: Helps understand code dependencies via a UML Dumper.
    • Control: Allows restricting how types are created using a Constructible Policy.
    • Performance: [Boost].DI has zero run-time overhead and fast compilation times.
  4. Boost.DI System Requirements and Compatibility

    cpp14

    Dependencies

    Boost.DI has no external dependencies; it does not require the STL or Boost libraries.

    Supported Compilers

    • Clang: 3.4+
    • GCC: 5.2+
    • MSVC: 2015+

    Thread Safety and Exceptions

    • Thread Safety: Boost.DI is thread safe.
    • Exception Safety: Boost.DI does not use exceptions internally and can be compiled with -fno-exceptions. Check the User Guide to see which specific APIs are marked noexcept.
  5. What is Dependency Injection (DI)?

    cpp14

    Dependency Injection (DI) is a design pattern where dependencies (services) are passed (injected) into a dependent object (client) during its construction, becoming part of the client's state. This follows the 'Hollywood principle' ('Don't call us, we'll call you').

    DI is similar to the Strategy Pattern, but the strategy is set once at construction. It enables loosely coupled designs that are easier to maintain and test by separating business logic from object creation.

    // Example of Dependency Injection vs No Dependency Injection
    
    // No Dependency injection
    class coffee_maker {
    public:
        void brew() {
            heater->on();
            pump->pump();
            clog << "coffee!" << endl;
            heater->off();
        }
    private:
        shared_ptr<iheater> heater = make_shared<electric_heater>();
        unique_ptr<ipump> pump = make_unique<heat_pump>(heater);
    };
    
    // Dependency Injection
    class coffee_maker {
    public:
        coffee_maker(const shared_ptr<iheater>& heater, unique_ptr<ipump> pump)
            : heater(heater), pump(move(pump))
        { }
    
        void brew() {
            heater->on();
            pump->pump();
            clog << "coffee!" << endl;
            heater->off();
        }
    private:
        shared_ptr<iheater> heater;
        unique_ptr<ipump> pump;
    };
  6. Understand di::deduce scope

    cpp14

    The di::deduce scope is the default behavior in Boost.DI. It automatically selects a scope based on the type being requested. This allows the library to intelligently manage lifetimes without explicit configuration for every binding.

    Deduction Rules:

    • T $\rightarrow$ [unique]
    • T& $\rightarrow$ [singleton]
    • const T& $\rightarrow$ [unique] (temporary) or [singleton]
    • T* or const T* $\rightarrow$ [unique] (ownership transfer)
    • T&& $\rightarrow$ [unique]
    • std::unique_ptr<T> $\rightarrow$ [unique]
    • std::shared_ptr<T> or boost::shared_ptr<T> $\rightarrow$ [singleton]
    • std::weak_ptr<T> $\rightarrow$ [singleton]
  7. Understand di::concepts::creatable

    cpp14

    The creatable concept defines the requirements for a type T that is intended to be instantiated via injector.create<T>(). It ensures that T is constructible with the provided arguments and that those arguments themselves are constructible using their own constructor traits.

    template <class T, class... TArgs>
        concept bool creatable() {
          return is_constructible<T, TArgs...>() &&
                 is_constructible<TArgs, type_traits::ctor_traits<TArgs>...>();
        }
  8. Structure a reveal.js theme file

    cpp14

    Each .scss theme file must follow a specific four-step structure to ensure variables and mixins are correctly applied during compilation:

    1. Include mixins: Import /css/theme/template/mixins.scss for shared utility functions.
    2. Include settings: Import /css/theme/template/settings.scss to declare the custom variables required by the template.
    3. Override defaults: This is where you customize the theme. You can either override the variables declared in step 2 or add custom selectors and styles.
    4. Include template: Import /css/theme/template/theme.scss. This template file generates the final CSS output based on the variables and styles defined in the previous steps.
  9. Structure reveal.js markup hierarchy

    cpp14

    To create a valid reveal.js presentation, you must follow a specific HTML hierarchy: a container with the class reveal, containing a slides div, which then contains one or more section elements. Each section represents a slide.

    To create vertical slides, nest multiple section elements inside another section. The first nested section acts as the root and is included in the horizontal sequence.

    <div class="reveal">
    	<div class="slides">
    		<section>Single Horizontal Slide</section>
    		<section>
    			<section>Vertical Slide 1</section>
    			<section>Vertical Slide 2</section>
    		</section>
    	</div>
    </div>
  10. Manage presentation size and scaling

    cpp14

    reveal.js automatically scales presentations based on a defined 'normal' size.

    Standard Scaling: Set width and height to your authoring resolution. The framework scales uniformly to fit the viewport.

    Custom Scaling (Manual): To disable automatic scaling and use your own (e.g., via CSS media queries), set width/height to 100%, margin to 0, and scale bounds to 1.

    Example Configuration:

    Reveal.initialize({
    	width: 960,
    	height: 700,
    	margin: 0.1,
    	minScale: 0.2,
    	maxScale: 1.5
    });
  11. Understand di::concepts::boundable for binding validation

    cpp14

    The boundable concept is a type constraint used during bindings to ensure that the relationship between an expected type and a given type is valid. A binding is boundable if the types are complete and the 'given' type is either a base of the 'expected' type or is convertible to it.

    Common boundable Error Messages: If a binding fails the concept check, you may encounter these errors:

    • type<T>::has_disallowed_qualifiers: The type T has disallowed qualifiers.
    • type<T>::is_abstract: The type T is abstract. (Set BOOST_DI_CFG_DIAGNOSTICS_LEVEL to 2 for more info).
    • type<T>::is_not_related_to: Type T is not related to the required type U.
    • type<T>::is_bound_more_than_once: Type T is bound more than once.
  12. Use and configure Speaker Notes

    cpp14

    Speaker notes allow you to present per-slide notes in a separate browser window (accessible by pressing the S key).

    Defining Notes

    1. HTML <aside> element: Append an <aside class="notes"> to a <section>.
    2. Markdown: Add the data-markdown attribute to the <aside> element.
    3. data-notes attribute: Add notes directly to the slide via <section data-notes="Your notes here"></section>.
    4. External Markdown: Use the data-separator-notes attribute to define the delimiter for notes.

    Configuration

    • showNotes: (boolean) If set to true, notes appear at the bottom of the presentation for all viewers.
    • showNotes: "separate-page": When exporting to PDF, this prints notes on a separate page after the slide instead of in a box on top of the slide.
    • defaultTiming: (number) Specifies the number of seconds per slide to enable the pacing timer. Can be set per slide using data-timing.
    <section>
    	<h2 class="title">Some Slide</h2>
    
    	<aside class="notes">
    		Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit »S« on your keyboard).
    	</aside>
    </section>