boost-ext / di

C++14 Dependency Injection Library
https://boost-ext.github.io/di
1.14k stars 138 forks source link

Runtime injector crashes on implementation with multiple interfaces #461

Open dagophil opened 4 years ago

dagophil commented 4 years ago

The runtime injector extension crashes (at runtime) if a single implementation is bound to multiple interfaces. Take the following class structure:

struct FirstInterface {
    virtual ~FirstInterface() noexcept = default;
    virtual void foo() = 0;
};
struct SecondInterface {
    virtual ~SecondInterface() noexcept = default;
    virtual void bar() = 0;
};
struct Derived : FirstInterface, SecondInterface {
    void foo() override { }
    void bar() override { }
};
struct User {
    User(FirstInterface& f_first, SecondInterface& f_second)
        : m_first{f_first}, m_second{f_second}
    {}
    FirstInterface& m_first;
    SecondInterface& m_second;
};

Trying to create a User triggers an assertion:

using namespace boost::di;
auto injector = extension::runtime_injector{make_injector(
    bind<FirstInterface, SecondInterface>.to<Derived>())};
auto user = create<User>(injector);
Assertion failed: false && "Type not bound!", file [...]/boost/di/extension/providers/runtime_provider.hpp, line 26

When binding both interfaces separately, the code does not crash, but it produces two different instances of Derived:

using namespace boost::di;
auto injector = extension::runtime_injector{make_injector(
    bind<FirstInterface>.to<Derived>(),
    bind<SecondInterface>.to<Derived>())};
auto user = create<User>(injector);
// user.m_first and user.m_second now point to two different instances.

A "normal" injector works correctly and produces a single Derived instance in both cases.

Specifications