c++ - [Boost]::DI 从注入(inject)器创建唯一的 shared_ptr 对象

标签 c++ boost dependency-injection shared-ptr

使用这个示例代码,我希望得到的结果是 button1 和 button2 是两个独立的对象。

#include <iostream>
#include <memory>
#include "di.hpp"
namespace di = boost::di;

struct CommandQueue {
    void addCommand() {}
};

struct Control {
    Control( CommandQueue &cq ) : cq( cq ) {
        static int sid{};
        id = ++sid;
    }

    CommandQueue& cq;
    int id{};
};

int main() {

    auto injector = di::make_injector( di::bind<CommandQueue>().in(di::singleton) );

    auto button1 = injector.create<std::shared_ptr<Control>>();
    auto button2 = injector.create<std::shared_ptr<Control>>();

    std::cout << "button1->id = " << button1->id << std::endl;
    std::cout << "button2->id = " << button2->id << std::endl;

    return 0;
}

当前输出为:

button1->id = 1

button2->id = 1

而不是预期的:

button1->id = 1

button2->id = 2

CommandQueue 单例中删除 di::singleton 生命周期范围也没有修复它。 我知道默认情况下 shared_ptr 的生命周期范围是单例,但我认为这是指注入(inject)的依赖项而不是使用 create 创建的实际对象。

最佳答案

确实最简单的事情可能是

auto button1 = injector.create<Control>();
auto button2 = injector.create<Control>();

std::cout << "button1.id = " << button1.id() << std::endl;
std::cout << "button2.id = " << button2.id() << std::endl;

打印

button1.id = 1
button2.id = 2

如果您必须有共享指针,下一个最简单的事情就是

auto button1 = std::make_shared<Control>(injector.create<Control>());
auto button2 = std::make_shared<Control>(injector.create<Control>());

std::cout << "button1->id = " << button1->id() << std::endl;
std::cout << "button2->id = " << button2->id() << std::endl;

概念上您需要一个控制工厂,而不是一个控件。因此,您应该考虑从依赖容器创建一个工厂:

#include <boost/di.hpp>
#include <iostream>
#include <memory>
namespace di = boost::di;

struct CommandQueue {
    void addCommand() {}
};

struct Control {
    Control(CommandQueue &cq) : _cq(cq), _id(idgen()) { }

    int id() const { return _id; }

    struct Factory {
        Factory(CommandQueue& cq) : _cq(cq) {}
        CommandQueue& _cq;

        template <typename... Args>
        auto operator()(Args&&... args) const {
            return std::make_shared<Control>(_cq, std::forward<Args>(args)...);
        }
    };
  private:
    static int idgen() { static int sid{}; return ++sid; }
    CommandQueue &_cq;
    int _id{};
};

int main() {
    auto injector = di::make_injector(di::bind<CommandQueue>().in(di::singleton));

    auto factory = injector.create<Control::Factory>();
    auto button1 = factory();
    auto button2 = factory();

    std::cout << "button1->id = " << button1->id() << std::endl;
    std::cout << "button2->id = " << button2->id() << std::endl;
}

关于c++ - [Boost]::DI 从注入(inject)器创建唯一的 shared_ptr 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46833374/

相关文章:

c# - 我应该使用构造函数注入(inject)还是 IoC.Resolve?

c++ - 从 C++ 中的文件读取到行尾?

c++ - 生成随机掷骰子并测量结果的频率

boost io_service.accept : Get URI called

boost - 使用 Boost Graph Library 显示图形

java - @Resource 与 @Autowired

.net - 使用第三方依赖注入(inject)容器比使用我构建的容器有什么好处?

c++ - 比较 4 个变量以找到最低的 C++

c++ - 将对象作为函数参数发送时 move 语义

c++ - CUDA __host__ __device__ 变量