I begin to use boost.di and I don't get about unique scope. Documentation says:
Scope representing unique/per request value. A new instance will be provided each time type will be requested.
#include <boost/di.hpp>
#include <assert.h>
namespace di = boost::di;
class server {
public:
};
int main()
{
di::policies::constructible();
di::injector<client> injector = di::make_injector(//<my_conf>
di::bind<server>().in(di::unique)
);
std::shared_ptr<server> server1 = injector.create<std::shared_ptr<server>>();
std::shared_ptr<server> server2 = injector.create<std::shared_ptr<server>>();
assert(server1 != server2);
}
My assert failed! Why?
I trully believe you already found your answer for this, but I was studying this library and stumbled upon your question without answer here and thought it might be useful for others to find a written answer.
So, the key poiny is the return type of di::make_injector.
If you write like this snippet below you'll see the difference between asking for auto vs restricting it to injector.
auto injector = di::make_injector(//<my_conf>
di::bind<server>().in(di::unique)
);
std::cout << typeid(injector).name() << '\n';
di::injector<client> injector2 = di::make_injector(//<my_conf>
di::bind<server>().in(di::unique)
);
std::cout << typeid(injector2).name() << '\n';
For reference, I put together a test code (written for testing with Catch2) which one can further explore the idea.
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
#include <boost/di.hpp>
namespace di = boost::di;
struct server {
virtual ~server() noexcept = default;
// cannot be pure virtual because server has to be creatable to be called explicitly in
// the injector call.
virtual void dummy(){};
};
struct client : server {
void dummy() override {}
};
TEST_CASE("injector","[Unique scope should return new objects at the same type creation call]")
{
di::policies::constructible();
auto injector = di::make_injector(//<my_conf>
di::bind<server>().to<client>().in(di::unique)
);
SECTION("new_objects"){
std::shared_ptr<server> server1 = injector.create<std::shared_ptr<server>>();
std::shared_ptr<server> server2 = injector.create<std::shared_ptr<server>>();
CHECK((server1) != (server2));
auto [server3, server4] = injector.create<std::tuple<std::shared_ptr<server>,std::shared_ptr<server>>>();
CHECK(server3 != server4);
}
SECTION("in_constructor"){
struct example {
example(std::shared_ptr<server> sp1 /*unique*/
, std::shared_ptr<server> sp2 /*unique*/
) {
CHECK(sp1 != sp2);
}
};
auto ex = injector.create<example>();
}
}
I hope this helps somebody to use this good library.