Introduction to Dependency Injection (DI)
Dependency Injection is a technique that allows an object to receive its dependencies ready for use at creation time instead of creating them internally. The DIPP (Dependency Injection for C++) library aims to closely resemble .NET's Microsoft Dependency Injection.
Features of DIPP
- Non-intrusive: Can be used with existing classes.
- No auto-registration: Services must be registered explicitly.
- Single registration: All services are registered once using
dipp::service_collectionwith specified descriptors (scope lifetime such as transient, scoped, or singleton, object's backing memory, and dependencies), and can later be consumed usingdipp::service_provider. - Extensible and flexible: Define your own service storage;
dipp::service_provideranddipp::service_collectionare templated storage, defaulting tostd::mapofdipp::move_only_any.
Error Handling Mode
DIPP supports two modes: error-based return values using Boost.Leaf, and exception throwing when trying to fetch or add a service (see error_handling.cpp for examples).
Keyed Services Support
Similar to .NET, DIPP supports keyed services, allowing multiple instances of the same type to be instantiated with different keys (see keys.cpp for examples).
Code Example
struct Engine {
Window& window1;
Window& window2;
Engine(Window& window1, Window& window2) : window1(window1), window2(window2) { }
};
// Declare our services
using WindowService1 = dipp::injected<Window, ...>;
using WindowService2 = dipp::injected<Window, ..., dipp::key("UNIQUE")>;
using EngineService = dipp::injected<Engine, ..., dipp::dependency<WindowService1, WindowService2>>;
// Create a collection to hold our services
dipp::service_collection collection;
// add the services to the collection
collection.add<WindowService>();
collection.add<EngineService>();
// create a service provider with the collection
dipp::service_provider services(std::move(collection));
// Fetch services
Engine& engine = services.get<EngineService>();
// both window services shouldn't be the same
assert(&engine.window1 != &engine.window2);
Resource Links
Blogger's Review: The DIPP library brings a flexible dependency injection mechanism to C++ developers, offering a .NET-like experience, particularly well-suited for modular development in large projects. It's worth delving into and applying!