google/fruit

Inject class that constructor with parameter 'vector<Writer*>'

zhlongfj opened this issue · 1 comments

//How can I inject class at function: 'getListenerComponent'?

using fruit::Component;
using fruit::Injector;

class Listener {
public:
virtual void notify() = 0;
};

class Listener1 : public Listener {
public:
INJECT(Listener1()) = default;

void notify() override {
    std::cout << "Listener 1 notified" << std::endl;
}

};

class Writer {
public:
virtual void write(std::string s) = 0;
};

// To show that we can inject parameters of multibindings
class StdoutWriter : public Writer {
public:
INJECT(StdoutWriter()) = default;

void write(std::string s) override {
    std::cout << "Stdout: " << s << std::endl;
}

};

fruit::Component getStdoutWriterComponent()
{
return fruit::createComponent().bind<Writer, StdoutWriter>();
}

class FileWriter : public Writer {
public:
INJECT(FileWriter()) = default;

void write(std::string s) override {
    std::cout << "File: " << s << std::endl;
}

};

fruit::Component getFileWriterComponent()
{
return fruit::createComponent().bind<Writer, FileWriter>();
}

fruit::Component<> getWritersComponent()
{
return fruit::createComponent()
.addMultibinding<Writer, StdoutWriter>()
.addMultibinding<Writer, FileWriter>();
}

class Listener2 : public Listener {
private:
Writer* writer;

public:
INJECT(Listener2(Writer* writer)) : writer(writer) {}

void notify() override {
    writer->write("Listener 2 notified");
}

};

class CListener : public Listener {
private:
std::vector<Writer*> writers;

public:
INJECT(CListener(std::vector<Writer*> writers)): writers(writers) {}

void notify() override {
    for (Writer *item : writers) {
        item->write("CListner: ");
    }
}

};

Component getListenerComponent() {
//how can I bind Listener?
}

Hi, you can only get a vector of multibindings out of an injector, you can't inject it.

What are you trying to do?
With such a specific question we risk running into the XY problem (https://xyproblem.info/), please give more info on what you're actually trying to do (I imagine it's some real-world thing and not just this example).

If using multibinders is actually the best solution for your case, you'll want to get them out of the injector and pass them explicitly in e.g. a method argument of a class injected from the injector, or using the vector to call an injected factory of the type you want.