C++模板在编译期构建依赖注入系统,通过Injectable基类标识可注入类型,std::tuple描述依赖关系,Injector模板类静态推导构造顺序并托管实例生命周期。

用C++模板在编译期构建依赖注入系统,避免运行时反射开销和虚函数调用,让对象创建、生命周期管理和依赖绑定全部由编译器推导完成。
定义可注入的组件接口
声明一个空基类 Injectable,所有需被注入的类型必须显式继承它,否则编译器无法识别其注入资格。
在头文件中写入:struct Injectable {};
这一步不可省略——【未继承 Injectable 的类型在后续注入解析中会被静默忽略,不会报错但也不会被构造】。
立即学习“C++免费学习笔记(深入)”;
实现依赖关系描述元组
使用 std::tuple 封装一组类型,表示某组件所依赖的其他组件集合。
例如:组件 ServiceA 依赖 Logger 和 Config,就定义 using deps = std::tuple<logger config>;</logger>
每个组件类内部必须提供名为 deps 的公开类型别名,且该别名必须为 std::tuple<...> 形式;若无依赖,则写为 using deps = std::tuple<>;。
编写注入上下文容器
定义模板类 Injector,接受一个参数包 Components...,代表当前容器能管理的所有组件类型。
在类内声明私有成员:std::tuple<:unique_ptr>...> m_instances;</:unique_ptr>
这个元组按 Components 参数顺序存储各组件的唯一指针,确保类型位置与模板参数顺序严格一致——【顺序错一位会导致 get<T>() 返回错误类型的指针,引发未定义行为】。
提供公共方法 template<typename T> T& get() { ... },通过 std::get<T>(m_instances) 获取对应实例;若为空则调用 create<T>() 构造。
实现编译期依赖图展开与构造顺序推导
第一步:定义辅助结构 dependency_order<T>,递归提取 T::deps 中每个类型的 deps,合并去重后生成依赖前置列表。
第二步:使用 std::integer_sequence 对组件类型列表排序,使依赖项总出现在被依赖项之前。
第三步:在 Injector 构造函数中,按此顺序依次调用 create<Component>(),确保每次构造时其所有依赖均已就绪。
这三步共同构成静态拓扑排序,完全在编译期完成;没有递归模板实例化深度超限风险,因最大依赖链长受编译器限制(通常 ≥ 256)。
注入实例的创建与生命周期管理
方法一:自动构造
在 create<T>() 中检查 T 是否有默认构造函数,若有且其 deps 元组为空,则直接 new T()。
方法二:带依赖构造
若 T::deps 非空,从 m_instances 中按 deps 类型顺序取出对应引用,转发给 T 的构造函数:new T(get<D1>(), get<D2>(), ...)。
方法三:自定义工厂支持
允许组件特化 create_instance 函数对象,返回 std::unique_ptr<T>;Injector 优先调用该特化版本而非默认构造。
所有创建出的实例均托管于 m_instances 元组中,随 Injector 生命周期自动析构,无需手动释放。


















