TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 229 subscribers
Post #24825 15
I made a single-header, non-intrusive IoC Container in C++17

[https://github.com/SirusDoma/Genode.IoC](https://github.com/SirusDoma/Genode.IoC)

A non-intrusive, single-header IoC container for C++17.

I was inspired after stumbling across a compiler loophole I found [here](https://alexpolt.github.io/type-loophole.html). Just now, I rewrote the whole thing without relying on that loophole because I just found out that my game sometimes won't compile on clang macOS without some workarounds.

Anyway, this is a similar concept to Java Spring, or C# Generic Host / Autofac, but unlike [kangaru](https://github.com/gracicot/kangaru) or other IoC libraries, this one is single header-only and most importantly: **non-intrusive**. Meaning you don't have to add anything extra to your classes, and it just works.

I have used this previously to develop a [serious game](https://www.reddit.com/r/gamedev/comments/1rldvqa/i_remade_an_online_retro_game_by_reverse/) with complex dependency trees (although it uses a previous version of this library, please check that link, it's made with C++ too), and a game work-in-progress that I'm currently working on with the new version I just pushed.

Template programming is arcane magic to me, so if you found something flawed / can be improved, please let me know and go easy on me 😅

**EDIT**

As requested, let me briefly talk about what IoC is:

IoC container stands for [Inversion of Control](https://en.wikipedia.org/wiki/Inversion_of_control), as mentioned, a similar concept to [Spring in Java](https://docs.spring.io/spring-framework/reference/core/beans/introduction.html). By extension, it is a [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection) pattern that manages and abstracts dependencies in your code.

Imagine you have the following classes in your app:

struct NetworkSystem
{
NetworkSystem(Config& c, Logger& l, Timer& t, Profiler* p)
: config(&c), logger(&l), timer(&t), profiler(&p) {}

Config* config; Logger* logger; Timer* timer; Profiler *profiler;
};

In a plain old-school way, you initialize the `NetworkSystem` by doing this:

auto config = Config(fileName);
auto logger = StdOutLogger();
auto timer = Timer();
auto profiler = RealProfiler(someInternalEngine, someDependency, etc);

auto networkSystem = NetworkSystem(config, logger, timer, profiler);

And you have to manage the lifetime of these components individually. With IoC, you could do something like this:

auto ioc = Gx::Context(); // using my lib as example

// Using custom init
// All classes that require config in their constructor will be using this config instance as long as they are created via this "ioc" object.
ioc.Provide<Config>([] (auto& ctx) {
return std::make_unique<Config>(fileName);
});

// Usually you have to tell container which concrete class to use if the constructor parameter relies on abstract class
// For example, Logger is an abstract class and you want to use StdOut
ioc.Provide<Logger, StdOutLogger>();

// Now simply call this to create network system
networkSystem = ioc.Require<NetworkSystem>(); // will create NetworkSystem, all dependencies created automatically inside the container, and it will use StdOutLogger

That's the gist of it. Most of the IoC container implementations are customizable, meaning you can control the construction of your class object if needed and automate the rest.

Also, the lifetime of the objects is tied to the IoC container; this means if the container is destroyed, all objects are destroyed (typically with some exceptions; in my lib, using `Instantiate<T>` returns a `std::unique_ptr<T>`). On top of that, depending on the implementation, some libraries provide sophisticated ways to manage the lifetime.

I would suggest familiarizing yourself with the IoC pattern before trying it out to avoid anti-patterns: For example, passing the container itself to the constructor is considered an anti-pattern. The following code
GitHub GitHub - SirusDoma/Genode.IoC: A non-intrusive single file header IoC Container for C++ 17 A non-intrusive single file header IoC Container for C++ 17 - SirusDoma/Genode.IoC
More from @r_cpp
  1. Oct 7, 2026Full Meeting C++ 2026 program released https://meetingcpp.com/mcpp/schedule/#2026 https://…
  2. Oct 7, 2026Qt moc now can handle basic C++ modules (Qt 6.12) https://codereview.qt-project.org/c/qt/q…
  3. Oct 7, 2026New to c++ Hello everybody,im new to cpp,and want to learn it,i have some knowledge with C…
  4. Oct 7, 2026Optimizing the Compressed Log Pipeline: https://github.com/Tencent/BqLog/blob/main/docs/Ar…
  5. Oct 7, 2026BqLog 2.6.0: a C++ logging library running on 30M+ devices daily, benchmarked against quil…
  6. Oct 7, 2026BqLog 2.6.0: a C++ logging library running on 30M+ devices daily, benchmarked against quil…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →