You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Kangaru C++自动装配功能简化依赖注入代码

基于Kangaru实现自动装配的依赖注入方案

当你尝试直接使用kgr::autowire实现BService时失败,核心原因是Kangaru自动装配无法默认推断抽象类型IA对应的服务实现。框架需要明确知道抽象接口与服务类的映射关系,以下是两种可行的解决方案:

方案一:注册抽象类型与服务的映射

通过特化kgr::service_map,告诉框架当需要IA类型实例时,使用IAService提供的实现:

#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> {};

// 关键:映射抽象类型IA到服务IAService
namespace kgr {
    template<>
    struct service_map<IA> {
        using type = IAService;
    };
}

// 使用autowire自动装配依赖
struct BService : kgr::single_service<B, kgr::autowire>, kgr::overrides<IBService> {};

int main()
{
    kgr::container container;

    container.service<AService>().run();
    container.service<IAService>().run();

    container.service<BService>().runB();
    container.service<IBService>().runB();
    
    return 0;
}

方案二:在构造函数中显式指定依赖服务

修改B的构造函数,使用kgr::inject<T>包装依赖的服务类型,让自动装配直接定位到IAService:

#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;

    // 使用kgr::inject指定依赖的服务
    B(kgr::inject<IAService> a)
        : _a(a.get())
    {}

    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> {};

// 直接使用autowire即可
struct BService : kgr::single_service<B, kgr::autowire>, kgr::overrides<IBService> {};

int main()
{
    kgr::container container;

    container.service<AService>().run();
    container.service<IAService>().run();

    container.service<BService>().runB();
    container.service<IBService>().runB();
    
    return 0;
}

注意事项

  • 原代码中的void main()不符合C++标准,需改为int main()并返回0,避免编译器兼容性问题。
  • 两种方案都能实现自动装配,选择哪种取决于你的代码风格:方案一更适合全局统一映射抽象类型,方案二则更直观地在构造函数中声明依赖服务。

内容的提问来源于stack exchange,提问作者Y.H.Cohen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 09:05:40