redi is a dependency injection library focusing on providing a great developer experience.
#include <cstdio>
#include <optional>
import redi;
struct WindowSystem {};
struct RenderSystem {
explicit RenderSystem(std::optional<WindowSystem&> window_system)
: window_system{ window_system }
{}
std::optional<WindowSystem&> window_system;
};
template <>
struct redi::EntryTraits<RenderSystem> {
static void describe_build(redi::BuildDirector<RenderSystem>& build_director)
{
build_director.use_dependencies<std::optional<WindowSystem&>>();
}
};
int main()
{
/*
* Registering `RenderSystem` automatically registers `WindowSystem`
* as well when it is an unconditional dependency.
*/
redi::Registry registry = redi::RegistryBuilder{}
.register_entry<RenderSystem>()
// order doesn't matter
.register_entry<WindowSystem>()
.build();
/*
* `RenderSystem` is never headless when `WindowSystem` is present
*/
std::puts(
registry.at<RenderSystem>().window_system.has_value()
? "Renderer is not headless"
: "Renderer is headless"
);
}- Automatic dependency injection
- Dependencies are automatically registered. You only need to register the concrete types you use.
- Optional dependencies
- Feel free to describe all the optional dependencies your types may need. They will be delivered when they are present.
- Support for configurable builder objects
- Use the builder method for complex building patterns.
- Elegant error messages
Cyclic dependency detected - entry of type `WindowSystem` depends on itself (WindowSystem -> RenderSystem -> WindowSystem) - Optimized for compile times
rediintentionally bypasses compile-time dependency detection. By eliminating the need to track transitive dependencies per source file, it significantly speeds up compilation.
Read the tutorial for an in-depth guide on how to inject dependencies using the library.
The library has no dependencies.
You can include it as a subdirectory, use FetchContent, or use Conan.
Read more about the specific Conan workflow here.