#include #include "matador/utils/di.hpp" #include namespace detail { class greeter { public: virtual ~greeter() = default; [[nodiscard]] virtual std::string greet() const = 0; }; class smart_greeter final : public greeter { public: [[nodiscard]] std::string greet() const override { return "hey dude"; } }; class hello_greeter final : public greeter { public: [[nodiscard]] std::string greet() const override { return "hello"; } }; class vehicle { public: virtual ~vehicle() = default; [[nodiscard]] virtual long id() const = 0; }; class truck final : public vehicle { public: truck() : id_(++id_counter_) {} [[nodiscard]] long id() const override { return id_; } private: static long id_counter_; long id_{}; }; long truck::id_counter_ = 0; class unknown {}; class per_thread { public: virtual ~per_thread() = default; virtual void dump() = 0; }; class per_thread_dumper final : public per_thread { public: explicit per_thread_dumper(std::string name ) : name_(std::move(name)) {} void dump() override { std::cout << name_ << ": thread id " << std::this_thread::get_id() << "\n"; } private: std::string name_; }; } using namespace matador::utils; TEST_CASE("Test dependency injection", "[dependency-injection]") { di::install_module([](di::module &module) { module.bind()->to_singleton(); }); di::inject g1; REQUIRE(g1); auto g2 = g1; REQUIRE(g2); REQUIRE(g1 == g2); g2 = std::move(g1); REQUIRE(!g1); REQUIRE(g2); REQUIRE(g1 != g2); auto g3(std::move(g2)); REQUIRE(!g2); REQUIRE(g3); REQUIRE(g3 != g2); di::module m; m.bind()->to_singleton(); m.bind("smart")->to_singleton(); di::inject g4(m, "smart"); REQUIRE(g4); REQUIRE(g4->greet() == "hey dude"); di::inject g5(m); REQUIRE(g5); REQUIRE(g5->greet() == "hello"); REQUIRE(g4 != g5); // UNIT_ASSERT_EXCEPTION(matador::di::inject u, std::logic_error, "unknown type"); }