### Install Hypodermic Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Command to install Hypodermic after building it. This typically involves using 'make install' which copies header files and libraries to their designated locations. ```bash $ pwd /home/yohan/hypodermic/build $ sudo make install ``` -------------------------------- ### Injecting a Single Instance (Persister) Source: https://github.com/ybainier/hypodermic/wiki/Expressing-dependencies Demonstrates how to inject a single instance of a dependency, such as `Configuration` and `ISerializer`, into the constructor of the `Persister` class. ```cpp class Persister { public: Persister(const std::shared_ptr< Configuration >& configuration, const std::shared_ptr< ISerializer >& serializer); }; ``` -------------------------------- ### Injecting All Instances of a Kind (ConfigManager) Source: https://github.com/ybainier/hypodermic/wiki/Expressing-dependencies Shows how to inject all available instances of a specific type, like `IConfiguration`, into a `std::vector` within the `ConfigManager` constructor. ```cpp class ConfigManager { public: ConfigManager(const std::vector< std::shared_ptr< IConfiguration > >& confs); }; ``` -------------------------------- ### Injecting the Container (HandlerInvoker) Source: https://github.com/ybainier/hypodermic/wiki/Expressing-dependencies Demonstrates injecting the dependency injection container itself, typically as a `std::weak_ptr`, allowing components to resolve other dependencies during their lifetime. Includes an example of resolving a handler within the `invoke` method. ```cpp template class HandlerInvoker { public: explicit HandlerInvoker(const std::shared_ptr< Container >& container); void invoke() { auto container = m_container.lock(); auto handler = m_container->resolve< THandler >(); } private: std::weak_ptr< Container > m_container; }; ``` -------------------------------- ### Hypodermic pkg-config File Generation Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic/CMakeLists.txt Configures and installs the pkg-config file for the Hypodermic library. This allows other projects to easily find and link against Hypodermic using pkg-config. ```cmake set(VERSION "${HYPODERMIC_VERSION}") set(prefix "${CMAKE_INSTALL_PREFIX}") set(exec_prefix "${prefix}") set(includedir "${prefix}/include") configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/libhypodermic.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libhypodermic.pc @ONLY) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libhypodermic.pc DESTINATION lib/pkgconfig ) ``` -------------------------------- ### Basic Component Registration Source: https://github.com/ybainier/hypodermic/wiki/Regarding-the-shared-pointers A simple example of registering a type 'Dispatcher' and aliasing it to the 'IDispatcher' interface. This is a fundamental step in dependency injection configuration. ```cpp builder.registerType< Dispatcher >().as< IDispatcher >(); ``` -------------------------------- ### Project Versioning and Setup Source: https://github.com/ybainier/hypodermic/blob/master/CMakeLists.txt Defines the project name and version numbers (major, minor, patch) for Hypodermic. It also enables testing infrastructure. ```cmake project(Hypodermic) cmake_minimum_required(VERSION 2.6) set(HYPODERMIC_VERSION_MAJOR "2") set(HYPODERMIC_VERSION_MINOR "5") set(HYPODERMIC_VERSION_PATCH "0") set(HYPODERMIC_VERSION "${HYPODERMIC_VERSION_MAJOR}.${HYPODERMIC_VERSION_MINOR}.${HYPODERMIC_VERSION_PATCH}" ) enable_testing() ``` -------------------------------- ### Service Class with Notification Integration Source: https://github.com/ybainier/hypodermic/blob/master/resources/home_page_simple_diagram_source.txt Describes the Service class which has a dependency on INotificationSender. The service has a start method and includes a note indicating that a notification is sent when the service starts. ```APIDOC Service: +start() <> note: Send a notification when the service is started{bg:wheat} ``` -------------------------------- ### Injecting an Instance Factory (PipeLoader) Source: https://github.com/ybainier/hypodermic/wiki/Expressing-dependencies Illustrates injecting a factory function (using `std::function`) that creates components on demand, which helps in avoiding circular dependencies. The factory returns a `std::shared_ptr`. ```cpp class PipeLoader { public: explicit PipeLoader(const std::function< std::shared_ptr< IPipe >() >& factory); }; // Example of the generated lambda with a weak pointer to the container: // [container]() { return container.lock()->resolve< T >(); }; ``` -------------------------------- ### Custom Container Builder Example Source: https://github.com/ybainier/hypodermic/wiki/Merging-containers Demonstrates inheriting from `ContainerBuilder` to create a `BusContainerBuilder`. This builder registers various types such as `BusConfiguration`, `MessageSerializer`, `ZmqTransport`, `PersistentTransport`, and `Core::Bus` with specific interfaces and single-instance lifetimes. It showcases dependency injection by specifying implementations for interfaces. ```cpp class BusContainerBuilder : public ContainerBuilder { public: BusContainerBuilder { registerType< BusConfiguration >() .as< Configuration::IConfiguration >() .asSelf() .singleInstance(); registerType< Serialization::MessageSerializer >() .as< Serialization::IMessageSerializer >() .singleInstance(); registerType< Transport::ZmqTransport >().singleInstance(); registerType< Persistence::PersistentTransport >() .with< Transport::ITransport, Transport::ZmqTransport >() .as< Persistence::IPersistentTransport >() .as< Transport::ITransport >() .singleInstance(); registerType< Core::Bus >() .as< IBus >() .as< Dispatch::IMessageDispatchFactory >() .singleInstance(); } }; ``` -------------------------------- ### Registering an Instance Source: https://github.com/ybainier/hypodermic/wiki/Registering-components Shows how to register a pre-existing instance with the ContainerBuilder. The container will provide this specific instance when requested, rather than creating a new one. ```cpp ContainerBuilder builder; auto configuration = std::make_shared< DispatcherConfiguration >(); builder.registerInstance(configuration); ``` -------------------------------- ### Resolving and Using IMessageWriter Source: https://github.com/ybainier/hypodermic/wiki/Getting-started Shows how to resolve an instance of `IMessageWriter` from the Hypodermic container and use it to write a message. The container automatically handles the injection of its dependencies. ```cpp void Application::run() { // Container, give us an instance of `IMessageWriter`. auto messageWriter = m_container->resolve< IMessageWriter >(); // Alright then, we can write some message. messageWriter->write("The app is running"); } ``` -------------------------------- ### Hypodermic Container Initialization Source: https://github.com/ybainier/hypodermic/wiki/Getting-started Demonstrates how to initialize a Hypodermic `ContainerBuilder` and register concrete types for the `IMessageSerializer` and `IMessageWriter` interfaces. This sets up the dependency injection container. ```cpp #include "Hypodermic/Hypodermic.h" class Application { public: Application() { // Components are registered in a ContainerBuilder Hypodermic::ContainerBuilder builder; // What we say here is: when I need an IMessageSerializer, // I want you to use this implementation. builder.registerType< LengthPrefixedMessageSerializer >() .as< IMessageSerializer >(); builder.registerType< ConsoleMessageWriter >().as< IMessageWriter >(); // Actually build the `Container` we have just configured. m_container = builder.build(); } // We will implement this one in a second void run(); private: std::shared_ptr< Hypodermic::Container > m_container; } ``` -------------------------------- ### Boost Dependency Handling Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic.Tests/CMakeLists.txt Finds and includes necessary Boost components (system, unit_test_framework) and sets up include and link directories. ```cmake find_package(Boost COMPONENTS system unit_test_framework) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) endif() ``` -------------------------------- ### Build Hypodermic on Linux Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Instructions for building Hypodermic on a Linux system using CMake. This involves creating a build directory, navigating into it, running CMake to configure the build, and then using make to compile the project. ```bash $ pwd /home/yohan/hypodermic $ mkdir build $ cd build $ cmake .. $ make ``` -------------------------------- ### Registering an Instance Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Demonstrates how to register a pre-created instance of a component (Driver) with the ContainerBuilder. The registered instance will be shared across the application. ```cpp ContainerBuilder builder; auto driver = std::make_shared< Driver >(); builder.registerInstance(driver); ``` -------------------------------- ### Validating Container with Missing Registration Source: https://github.com/ybainier/hypodermic/wiki/Validation This example shows a scenario where a required interface registration is missing. When `validate()` is called, it will throw an exception because a dependency (`IMessageSerializer`) cannot be resolved, highlighting the importance of complete registrations. ```cpp Hypodermic::ContainerBuilder builder; builder.registerType< LengthPrefixedMessageSerializer >(); builder.registerType< ConsoleMessageWriter >().as< IMessageWriter >(); builder.validate(); ``` -------------------------------- ### Registering a Factory Source: https://github.com/ybainier/hypodermic/wiki/Registering-components Illustrates how to register a factory function that the container will call to create instances. This is useful for complex object creation logic or when dependencies are needed for instantiation. ```cpp ContainerBuilder builder; builder.registerInstanceFactory([](ComponentContext&) { return std::make_shared< ThreadPool >(std::thread::hardware_concurrency()); }); ``` -------------------------------- ### Resolving a Dependency with a Nested Container Source: https://github.com/ybainier/hypodermic/wiki/Controlling-lifetime Demonstrates how a nested container can provide dependencies for objects registered in a parent container. This example shows a `Persister` depending on `Configuration`, with `Configuration` registered in the nested container. ```cpp class Persister { public: Persister(const std::shared_ptr< Configuration >& configuration) { if (configuration == nullptr) throw std::invalid_argument("configuration"); } }; ContainerBuilder builder; builder.registerType< Persister >(); auto container = builder.build(); // This would throw because Configuration is not registered in the parent container // auto persister = container->resolve< Persister >(); ContainerBuilder anotherBuilder; anotherBuilder.registerType< Configuration >(); auto nestedContainer = anotherBuilder.buildNestedContainerFrom(*container); auto persister = nestedContainer->resolve< Persister >(); ``` -------------------------------- ### Concrete Implementations: Serializer and Writer Source: https://github.com/ybainier/hypodermic/wiki/Getting-started Provides concrete implementations for the message handling interfaces. `LengthPrefixedMessageSerializer` writes the message length before the message content. `ConsoleMessageWriter` uses a serializer to write messages to the console. ```cpp class LengthPrefixedMessageSerializer : public IMessageSerializer { public: void serialize(const std::string& message, std::ostream& stream) override { stream << message.size(); stream << message; } }; class ConsoleMessageWriter : public IMessageWriter { public: explicit ConsoleMessageWriter(std::shared_ptr< IMessageSerializer > serializer) : m_serializer(serializer) { } void write(const std::string& message) override { m_serializer->serialize(message, std::cout); } private: std::shared_ptr< IMessageSerializer > m_serializer; }; ``` -------------------------------- ### Hypodermic Tests Source Files Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic.Tests/CMakeLists.txt Lists all source files used for building the Hypodermic.Tests executable, including the main entry point and various test files. ```cmake set(HypodermicTests_sources main.cpp CircularDependencyTests.cpp ContainerBuilderTests.cpp ContainerTests.cpp DefaultConstructibleTests.cpp FactoryTests.cpp IsCompleteTests.cpp MemoryTests.cpp NamedTests.cpp NestedContainerTests.cpp PerformanceTests.cpp PersistentInstanceRegistrationTests.cpp ProvidedDependenciesTests.cpp ProvidedInstanceFactoryRegistrationTests.cpp ProvidedInstanceRegistrationTests.cpp RegistrationTests.cpp RuntimeRegistrationTests.cpp UseIfNoneTests.cpp ) ``` -------------------------------- ### Message Serialization and Writing Interfaces Source: https://github.com/ybainier/hypodermic/wiki/Getting-started Defines the core interfaces for message serialization and writing. `IMessageSerializer` handles the serialization logic, while `IMessageWriter` handles the overall writing process, depending on a serializer. ```cpp class IMessageSerializer { public: virtual ~IMessageSerializer() = default; virtual void serialize(const std::string& message, std::ostream& stream) = 0; }; class IMessageWriter { public: virtual ~IMessageWriter() = default; virtual void write(const std::string& message) = 0; }; ``` -------------------------------- ### CMake Project Configuration Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic.Tests/CMakeLists.txt Configures the CMake project for Hypodermic.Tests, specifying the minimum required CMake version and finding necessary packages like Boost. ```cmake project(Hypodermic.Tests) cmake_minimum_required(VERSION 2.6) ``` -------------------------------- ### Executable and Library Linking Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic.Tests/CMakeLists.txt Defines the Hypodermic.Tests executable and links it against the Boost libraries. Also includes a definition for dynamic linking of Boost.Test. ```cmake include_directories("..") add_definitions(-DBOOST_TEST_DYN_LINK) add_executable(Hypodermic.Tests ${HypodermicTests_sources}) target_link_libraries(Hypodermic.Tests ${Boost_LIBRARIES}) ``` -------------------------------- ### Registering a Type Source: https://github.com/ybainier/hypodermic/wiki/Registering-components Demonstrates how to register a concrete type with the ContainerBuilder. This allows the container to create instances of this type when requested. ```cpp ContainerBuilder builder; builder.registerType< MessageDispatcher >(); ``` -------------------------------- ### Registering Type with AsSelf Source: https://github.com/ybainier/hypodermic/wiki/Registering-components Illustrates how to explicitly register a type to be resolvable by both its concrete type and its abstraction. This is often used in conjunction with the 'as' method. ```cpp ContainerBuilder builder; builder.registerType< MessageDispatcher >().as< IMessageDispatcher >().asSelf(); ``` -------------------------------- ### Post-Build Custom Command Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic.Tests/CMakeLists.txt Adds a custom command to execute the Hypodermic.Tests executable after the target is built. ```cmake add_custom_command(TARGET Hypodermic.Tests POST_BUILD COMMAND ${CMAKE_CURRENT_BINARY_DIR}/Hypodermic.Tests) ``` -------------------------------- ### Type Autowiring Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Explains how to use `AutowiredSignature` to describe a type's constructors, allowing Hypodermic to automatically resolve and inject dependencies without explicit lambda expressions. ```cpp class Car : public ICar { public: typedef AutowiredConstructor< Car(IDriver*) > AutowiredSignature; Car(std::shared_ptr< IDriver > driver); } // Registration: builder.autowireType< Car >()->as< ICar >(); builder.registerType< Driver >()-as< IDriver >(); ``` -------------------------------- ### Registering a Type with a Lambda Expression Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Illustrates registering a type using a lambda expression that provides custom logic for creating an instance of the component. The CREATE macro simplifies this process. ```cpp builder.registerType< Driver >( [](IComponentContext&) -> Driver* { return new Driver; })); // Using the CREATE macro: builder.registerType< Driver >(CREATE(new Driver)); ``` -------------------------------- ### Registering a Concrete Type as Interfaces Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Demonstrates how to register a concrete type and expose it through multiple interfaces using the `as()` method for polymorphic resolution. ```cpp builder.registerType< Driver >()->as< IDriver >()->as< IRobot >(); ``` -------------------------------- ### Hypodermic Header Files Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic/CMakeLists.txt Lists all header files that are part of the Hypodermic library. These files define the interfaces and implementation details of the dependency injection framework. ```cmake set(Hypodermic_headers ActivatedRegistrationInfo.h ActivationException.h ActivationHandler.h ActivationHandlers.h ActivationRegistry.h ActivationResult.h AnyArgument.h ArgumentPack.h ArgumentResolver.h As.h AsSelf.h AutowireableConstructor.h AutowireableConstructorRegistrationDescriptor.h Behavior.h CircularDependencyException.h ComponentContext.h Config.h ConsoleLoggerSink.h ConstructorDescriptor.h ConstructorTypologyDeducer.h Container.h ContainerBuilder.h ContainerInstanceRegistration.h ContainerInstanceRegistrationActivator.h DependencyActivationException.h DependencyFactories.h DependencyFactory.h DependencyFactoryTag.h EnforceBaseOf.h EnforceDependencyNotAlreadyRegistered.h ExceptionBase.h FactoryWrapper.h Hypodermic.h ILoggerSink.h IMutableRegistrationScope.h InstanceAlreadyActivatingException.h InstanceFactory.h InstanceLifetime.h InstanceRegistrationTags.h IntegerSequence.h IRegistration.h IRegistrationActivator.h IRegistrationDescriptor.h IRegistrationRegistry.h IRegistrationScope.h IResolutionContainer.h IResolutionContext.h IRuntimeRegistrationBuilder.h IsComplete.h IsSupportedArgument.h ITypeAlias.h Log.h Logger.h LogLevel.h MetaContains.h MetaForEach.h MetaIdentity.h MetaInsert.h MetaMap.h MetaPair.h Named.h NamedTypeAlias.h NestedRegistrationScope.h NoopLoggerSink.h OnActivated.h PersistentInstanceRegistration.h PointerAlignment.h Pragmas.h ProvidedDependencyTag.h ProvidedInstanceDependencyTag.h ProvidedInstanceFactoryRegistrationDescriptor.h ProvidedInstanceRegistration.h ProvidedInstanceRegistrationActivator.h ProvidedInstanceRegistrationDescriptor.h Registration.h RegistrationActivator.h RegistrationBuilder.h RegistrationContext.h RegistrationDescriptorBase.h RegistrationDescriptorBuilder.h RegistrationDescriptorInfo.h RegistrationDescriptorInfoToString.h RegistrationException.h RegistrationScope.h ResolutionContainer.h ResolutionContext.h ResolutionException.h ResolutionInfo.h RuntimeRegistrationBuilder.h SingleInstance.h TypeAlias.h TypeAliases.h TypeAliasKey.h TypeInfo.h UseIfNone.h With.h ) install(FILES ${Hypodermic_headers} DESTINATION include/Hypodermic) ``` -------------------------------- ### Registering a Type Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Shows the basic way to register a type with the ContainerBuilder. Hypodermic will create a new instance of the specified type whenever it's resolved. ```cpp builder.registerType< Driver >(); ``` -------------------------------- ### Registering Type with Abstraction (As) Source: https://github.com/ybainier/hypodermic/wiki/Registering-components Explains how to register a type and make it resolvable by its abstraction (e.g., an interface). The container will provide an instance of the concrete type when an abstraction is requested. ```cpp ContainerBuilder builder; builder.registerType< MessageDispatcher >().as< IMessageDispatcher >(); ``` -------------------------------- ### Registering Instance Factories with Hypodermic Source: https://github.com/ybainier/hypodermic/wiki/Explicit-dependencies Shows how to register an instance factory (a lambda function) for a transport with Hypodermic. This allows for lazy instantiation and complex dependency resolution logic. ```cpp builder.registerType< SocketTransport >(); builder.registerType< PersistentTransport >() .with< ITransport >([](ComponentContext& context) { return context.resolve< SocketTransport >(); } .as< ITransport >(); ``` -------------------------------- ### Initializing Container with Custom Builder Source: https://github.com/ybainier/hypodermic/wiki/Merging-containers Shows how to initialize a `ContainerBuilder` by adding registrations from a custom builder, such as `BusContainerBuilder`. The `addRegistrations` method is used to merge configurations from one builder into another. ```cpp void initialize(ContainerBuilder& builder) { builder.addRegistrations(BusContainerBuilder()); } ``` -------------------------------- ### Expressing Dependencies with Lambda Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Shows how to define dependencies for a component (Car) using a lambda expression that resolves other components (IDriver) from the context. The INJECT macro simplifies dependency injection. ```cpp builder.registerType< Car >( [](IComponentContext& c) -> Car* { return new Car(c.resolve< IDriver >()); })); // Using the CREATE and INJECT macros: builder.registerType< Car >(CREATE(new Car(INJECT(IDriver)))); ``` -------------------------------- ### Tweaking Sharing Mode (Single Instance) Source: https://github.com/ybainier/hypodermic/wiki/Building-and-using-version-1 Demonstrates how to configure a registered type to be a single instance (singleton). Hypodermic will create only one instance of the type and reuse it for all subsequent resolutions. ```cpp builder.registerType< Driver >()->as< IDriver >()->singleInstance(); builder.registerType< Car >(CREATE(new Car(INJECT(IDriver))))->as< ICar >()->singleInstance(); ``` -------------------------------- ### Registering Type with Named Abstraction Source: https://github.com/ybainier/hypodermic/wiki/Registering-components Demonstrates registering a type with both an abstraction and a specific name. This allows for multiple implementations of the same abstraction to be registered and resolved by their names. ```cpp ContainerBuilder builder; builder.registerType< MessageDispatcher >() .named< IMessageDispatcher >("LeDispatcher"); auto leDispatcher = container->resolveNamed< IMessageDispatcher >("LeDispatcher"); ``` -------------------------------- ### CMake Test Execution Source: https://github.com/ybainier/hypodermic/blob/master/Hypodermic.Tests/CMakeLists.txt Configures a CMake test to run the Hypodermic.Tests executable with specific reporting options. ```cmake add_test(cmake_Hypodermic.Tests ${CMAKE_CURRENT_BINARY_DIR}/Hypodermic.Tests --result_code=no --report_level=no) ``` -------------------------------- ### Registering Types with Hypodermic Source: https://github.com/ybainier/hypodermic/wiki/Explicit-dependencies Demonstrates how to register different types of transports (SocketTransport, PersistentTransport) with the Hypodermic dependency injection container. It shows how to specify dependencies and aliases. ```cpp builder.registerType< SocketTransport >(); builder.registerType< PersistentTransport >() .with< ITransport, SocketTransport >() .as< ITransport >(); ``` -------------------------------- ### Packaging Configuration Source: https://github.com/ybainier/hypodermic/blob/master/CMakeLists.txt Sets up CPack for packaging the project, defining package version, source archive file name, and files to ignore during packaging. It also includes the CPack module and adds a 'dist' target to create a source distribution. ```cmake # Packaging stuff ################# # set(CPACK_PACKAGE_VERSION_MAJOR "${HYPODERMIC_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${HYPODERMIC_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${HYPODERMIC_VERSION_PATCH}") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${HYPODERMIC_VERSION}" ) set(CPACK_SOURCE_GENERATOR "TBZ2") set(CPACK_SOURCE_IGNORE_FILES "/.hg/" "/.hgignore$" "build/" "ipch/" "/resources/" ".sdf$;.suo$;.tss$" ) include(CPack) add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) ``` -------------------------------- ### Registering a Component with an Initialization Hook Source: https://github.com/ybainier/hypodermic/wiki/Activation-hooks Demonstrates how to register a C++ component (`HostInitializer`) with the Hypodermic dependency injection container. The `onActivated` hook is used to call the `initialize()` method on the component instance immediately after it's created. This ensures that the component is fully set up before it's resolved. ```cpp ContainerBuilder builder; builder.registerType< HostInitializer >() .as< IHostInitializer >() .onActivated([](ComponentContext&, const std::shared_ptr< HostInitializer >& instance) { instance->initialize(); }); auto container = builder.build(); auto initializer = container->resolve< IHostInitializer >(); ``` -------------------------------- ### Registering a Shared Instance Source: https://github.com/ybainier/hypodermic/wiki/Controlling-lifetime Demonstrates how to register an instance with the ContainerBuilder, ensuring it's shared across the application. The resolved instance is asserted to be the same as the registered one. ```cpp ContainerBuilder builder; auto configuration = std::make_shared< DispatcherConfiguration >(); builder.registerInstance(configuration); auto container = builder.build(); auto resolvedConfiguration = container->resolve< DispatcherConfiguration >(); assert(resolvedConfiguration == configuration); ``` -------------------------------- ### Building a Nested Container Source: https://github.com/ybainier/hypodermic/wiki/Controlling-lifetime Illustrates the creation of a nested container from an existing container. Components registered in the nested container are only resolvable within it. ```cpp ContainerBuilder builder; builder.registerType< MessageDispatcher >() .as< IMessageDispatcher >() .singleInstance(); // container is the instance of the container we already have built earlier auto nestedContainer = builder.buildNestedContainerFrom(*container); auto dispatcher = nestedContainer->resolve< IMessageDispatcher >(); ``` -------------------------------- ### Registering a Type as a Single Instance Source: https://github.com/ybainier/hypodermic/wiki/Controlling-lifetime Shows how to register a type and explicitly mark it as a single instance using `.singleInstance()`. This ensures that only one instance of the registered type is ever created and shared. ```cpp ContainerBuilder builder; builder.registerType< MessageDispatcher >() .as< IMessageDispatcher >() .singleInstance(); auto container = builder.build(); auto dispatcher1 = container->resolve< IMessageDispatcher >(); auto dispatcher2 = container->resolve< IMessageDispatcher >(); assert(dispatcher1 == dispatcher2); ``` -------------------------------- ### Performance Benchmarks: Default Constructible Type Source: https://github.com/ybainier/hypodermic/wiki/Benchmarks This table summarizes the performance of different dependency resolution strategies for a default constructible type. It includes metrics like overall time, average, min, max, and various percentiles for each resolution method. ```markdown | | std::make_shared | resolve not registered transient | resolve registered transient | resolve registered single instance | resolve registered instance | |--------------|-----------------:|---------------------------------:|-----------------------------:|-----------------------------------:|----------------------------:| | Overall (ms) | 10 | 71 | 70 | 54 | 55 | | Average | 0.07 | 0.68 | 0.67 | 0.51 | 0.52 | | Min | 0 | 0.57 | 0.57 | 0.28 | 0.28 | | Max | 43 | 149 | 267 | 87 | 268 | | 99.999% | 40 | 67 | 67 | 70 | 115 | | 99.99% | 22 | 41 | 30 | 24 | 24 | | 99.9% | 1 | 9 | 7 | 2 | 4 | | 99% | 0.28 | 0.86 | 0.86 | 0.57 | 0.57 | | 95% | 0.28 | 0.86 | 0.86 | 0.57 | 0.57 | | 50% | 0 | 0.57 | 0.57 | 0.57 | 0.57 | ```