因为项目轻量、嵌入式受限或需完全掌控生命周期与类型擦除,故手写DI:用std::function+std::any基于type_index注册,支持实例/工厂模式,编译期检查依赖,单例由injector统一管理析构。
为什么不用现成 DI 库,而要手写一个?
因为项目轻量、嵌入式环境受限、或想彻底掌控生命周期与类型擦除方式。标准库没有 std::injector,Boost.DI 又太重——你只需要注册几个单例服务,让类在构造时自动拿到依赖,不希望被模板爆炸或宏污染干扰。
核心诉求就三点:类型安全注册、无反射下的依赖发现、对象生命周期可控(尤其是单例 vs 每次新建)。
如何用 std::function + std::any 实现类型擦除注册表?
不能靠 RTTI 做运行时类型匹配(开销大且不可靠),也不能全靠模板推导(会导致每个注册点生成独立实例)。折中方案是:注册时存一个能构造目标类型的 std::function,查表时用 std::type_index 作 key,取值时用 std::any_cast 安全还原。
-
register_instance(T&& obj):直接存拷贝/移动后的对象,后续返回引用(适合单例) -
register_factory(std::function()> factory):每次调用都新建,适合有状态的短生命周期对象 - 所有注册项统一存进
std::unordered_map,key 是typeid(T)
注意:std::any 存 std::function 没问题,但别存裸指针或栈变量引用——生命周期必须比容器长。
立即学习“C++免费学习笔记(深入)”;
构造函数注入怎么绕过“循环依赖”和“未注册类型”?
C++ 没有运行时反射,无法自动扫描构造函数参数。所以“注入”其实是手动声明依赖关系:你在定义类时,显式写出它需要哪些接口,并在创建时由框架按需提供。