C++ Kangaru IOC库使用问题:依赖注入致程序崩溃排查
Kangaru IOC库使用问题解答
1. 代码中的错误分析
- BService定义存在两处关键错误:
- 多余的
kgr::supplied标记:该标记用于告知容器,服务实例由外部提供而非容器创建,但你的场景中B实例需要容器注入IA来初始化,添加此标记会导致容器无法正确创建B实例。 - 缺少
kgr::overrides<IBService>关联:IBService是抽象服务,BService作为其实现类的服务包装,必须通过overrides与IBService绑定,否则容器无法将IBService的请求映射到BService实现,调用container.service<IBService>()会返回无效引用,最终触发崩溃。
- 多余的
- 额外的冗余操作:
container.service<AService>()属于冗余调用,容器会在依赖该服务时自动完成初始化,无需显式触发。
2. 依赖定义是否必须?Kangaru能否自动推断依赖?
- 依赖定义并非强制要求,Kangaru支持自动推断依赖,但存在前提条件:
- 当服务构造函数的参数类型,已在容器中注册了对应的服务(非抽象接口,或抽象接口有对应的服务包装),Kangaru可自动推断依赖关系。
- 对于抽象接口类型的依赖(如代码中的
IA&),由于容器中注册的是IAService(抽象服务包装)而非IA本身,必须手动通过kgr::dependency<IAService>指定依赖,否则容器无法识别要注入的服务实例。 - 若使用
kgr::service而非kgr::single_service,且构造函数参数对应的类型均有已注册的服务,Kangaru可自动完成依赖推断,无需手动声明dependency。
修正后的代码示例
#include <kangaru/kangaru.hpp> #include <iostream> struct IA { virtual void run() const = 0; }; struct A : IA { void run() const override { std::cout << "A" << std::endl; } }; struct IB { virtual void runB() const = 0; }; struct B : IB { IA& _a; B(IA& a) : _a(a) {} void runB() const override { std::cout << "B" << std::endl; } }; struct IAService : kgr::abstract_service<IA> {}; struct IBService : kgr::abstract_service<IB> {}; struct AService : kgr::single_service<A>, kgr::overrides<IAService> {}; // 修正BService定义:移除supplied标记,添加与IBService的关联 struct BService : kgr::single_service<B, kgr::dependency<IAService>>, kgr::overrides<IBService> {}; int main() { kgr::container container; // 容器会自动初始化依赖的AService container.service<IAService>().run(); container.service<IBService>().runB(); }
内容的提问来源于stack exchange,提问作者Y.H.Cohen
相关产品推荐
相关产品推荐

