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

Lambda Expression Not Executing in Dynamic Array Binding for Interface Implementations with Boost.DI #562

Open
xuanjiYUU opened this issue Jun 5, 2024 · 0 comments

Comments

@xuanjiYUU
Copy link

I am encountering an issue where a lambda expression used to conditionally bind an array of interfaces (Log) based on runtime conditions is not being executed. This problem arises when using boost::di to manage dependency injection where the lambda is supposed to dynamically decide the creation of different implementations (ConsoleLog, FileLog) of the Log interface. Despite configuring the injector correctly, the lambda expression doesn't seem to be invoked at all.
Here is my code :

#include <boost/di.hpp>
#include <iostream>
#include <memory>
#include <vector>

namespace di = boost::di;

struct Log {
    virtual ~Log() = default;
    virtual void log(const std::string& message) = 0;
};

struct ConsoleLog : Log {
    void log(const std::string& message) override {
        std::cout << "ConsoleLog: " << message << std::endl;
    }
};

struct FileLog : Log {
    void log(const std::string& message) override {
        std::cout << "FileLog: " << message << std::endl;
    }
};

class A {
public:
    A(std::vector<std::shared_ptr<Log>>& logs) : logs_(logs) {
        std::cout << logs_.size() << std::endl;
        for (auto& p : logs_) {
            p->log("test A");
        }
    }

private:
    std::vector<std::shared_ptr<Log>>& logs_;
};

int main() {
    bool needConsole = true;
    bool needFile = false;

    auto injector = di::make_injector(
        di::bind<Log*[]>().to([&](const auto& injector) -> std::vector<std::shared_ptr<Log>> {
            std::vector<std::shared_ptr<Log>> logs;
            std::cout << "Lambda executing" << std::endl;
            if (needConsole) {
                logs.push_back(injector.template create<std::shared_ptr<ConsoleLog>>());
            }
            if (needFile) {
                logs.push_back(injector.template create<std::shared_ptr<FileLog>>());
            }
            return logs;
        }).in(di::singleton)
    );

    auto a = injector.create<A>();
    return 0;
}

Attempts to Resolve
Direct Call Test: Attempted to directly call the lambda by manually invoking the creation of the std::vector<std::shared_ptr> to ensure it's not an issue with how the lambda is set up.
Simplification: Reduced the complexity of the lambda to just create a single instance of ConsoleLog without any conditions to check if the lambda gets called.
Logging: Added extensive logging inside the lambda and around its invocation to track execution flow and verify whether the lambda is invoked.
Current Status
Despite these attempts, the lambda expression does not execute, and the injector seems to not resolve the dependencies as expected. The logging statements inside the lambda ("Lambda executing") are never printed, indicating that the lambda is not being triggered at all.

Request for Assistance
I am looking for guidance on whether there is a configuration mistake or a misunderstanding on my part regarding how boost::di manages lambda expressions for dependency injection. Any advice or insights into what might be causing this issue or how to resolve it would be greatly appreciated.

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