Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factory extension creating object instead of using value supplied in .create() #531

Open
dfontenot opened this issue Nov 23, 2021 · 0 comments

Comments

@dfontenot
Copy link

I'm running into an issue using the factory extension. It seems that the ref that is passed to the .create() method for the injected factory is ignored, and DI is instead instantiating a new one. It looks like DI is trying to create a NonInjected for me, but in this example I wanted to have NonInjected represent something that lives outside of the bindings. I used the existing guides on the website as a guide for the code.

Below is a little messy, and probably unnecessarily nested, because it's a rough translation of some existing code that removes its domain-specific stuff.

Please let me know if this is just a misunderstanding of how the library works.

Expected Behavior

Program output:

in usesfactoried
in NonInjected ctor 4.5
before <NonInjected d=4.5>
in factoried ctor <NonInjected d=4.5>
in factoried 42 <NonInjected d=4.5>

Actual Behavior

Program output:

in usesfactoried
in NonInjected ctor 4.5
before <NonInjected d=4.5>
in NonInjected ctor 0
in factoried ctor <NonInjected d=0>
in factoried 42 <NonInjected d=0>

Steps to Reproduce the Problem

#include <iostream>
#include <boost/di.hpp>
#include <boost/di/extension/injections/factory.hpp>
#include <memory>
#include <cassert>

namespace di = boost::di;
namespace ext = di::extension;

using std::make_unique;
using std::cout;
using std::endl;
using std::ostream;

// some class that isn't injected
class NonInjected {
    public:
    double d;

    explicit NonInjected(double d) : d(d) {
        cout << "in NonInjected ctor " << d << endl;
    }

    friend auto operator<<(ostream& os, NonInjected const& m) -> ostream& {
        return os << "<NonInjected d=" << m.d << ">";
    }
};

// some regular class that is injected
struct IRegular {
    virtual ~IRegular() noexcept = default;
};

class Regular : public IRegular {
public:
    explicit Regular(int i) : i(i) {}
    int i;
};

// is used as a factory
struct IFactoried {
    virtual ~IFactoried() noexcept = default;
    virtual void run() = 0;
};

class Factoried : public IFactoried {
    Regular reg_;
    NonInjected& notInjected_;

public:
    Factoried(Regular& reg, NonInjected& notInjected) :
        reg_(reg),
        notInjected_(notInjected) {

        cout << "in factoried ctor " << notInjected << endl;
    }

    void run() override {
        cout << "in factoried " << reg_.i << " " << notInjected_ << endl;
    }
};

using InjectableFactory = ext::ifactory<IFactoried, NonInjected& >;
using RealFactory = ext::factory<Factoried>;

// uses factoried as a factory

struct IUsesFactoried {
    virtual ~IUsesFactoried() noexcept = default;
    virtual void run() = 0;
};

class UsesFactoried : public IUsesFactoried {
    InjectableFactory& fac_;

public:
    UsesFactoried(InjectableFactory& fac) :
        fac_(fac) {}

    void run() override {
        cout << "in usesfactoried" << endl;

        auto managed = make_unique<NonInjected>(4.5);
        cout << "before " << *managed << endl;

        auto boxed = fac_.create(*managed);
        auto f = boxed.get();
        f->run();
    }
};

int main() {
    const auto injector = di::make_injector(
        di::bind<InjectableFactory>().to(RealFactory {}),
        di::bind<IRegular>().to<Regular>(),
        di::bind<IFactoried>().to<Factoried>(),
        di::bind<IUsesFactoried>().to<UsesFactoried>(),
        di::bind<int>().to(42)
    );

    auto output = injector.create<UsesFactoried>();
    output.run();
}

Specifications

  • Version: Latest on the cpp14 branch as of right now (3f72feb)
  • Platform: Linux, Clang 10.0.0-4ubuntu1
  • Subsystem:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant