Injecting Multiple Services#

Multiple services can inherit one interface and can be injected using a vector.

Note

Service objects are ordered in vectors using registration order. The last registered service with the same base type is used when resolving one service

Injection rules are simple:

  • It is guaranteed that vectors won’t contain null pointers

  • Singleton/scoped services should be injected using std::vector<pointers>

  • Transient services should be injected using std::vector<std::unique_ptr>

Examples/Guides/InjectingMultipleServices#
#include <SevenBit/DI.hpp>
#include <iostream>
#include <utility>

using namespace sb::di;

struct IWorker
{
    virtual std::string work() = 0;

    virtual ~IWorker() = default;
};
struct WorkerA final : IWorker
{
    std::string work() override { return "work A done!"; }
};
struct WorkerB final : IWorker
{
    std::string work() override { return "work B done!"; }
};
struct WorkerC final : IWorker
{
    std::string work() override { return "work C done!"; }
};

class ServiceExecutor
{
    std::vector<IWorker *> _workers;

  public:
    explicit ServiceExecutor(std::vector<IWorker *> workers) : _workers(std::move(workers)) {}

    [[nodiscard]] std::string workAll() const
    {
        std::string result;
        for (const auto worker : _workers)
        {
            result += worker->work() + " ";
        }
        return result;
    }
};
int main()
{
    ServiceProvider provider = ServiceCollection{}
                                   .addSingleton<IWorker, WorkerA>()
                                   .addSingleton<IWorker, WorkerB>()
                                   .addSingleton<IWorker, WorkerC>()
                                   .addSingleton<ServiceExecutor>()
                                   .buildServiceProvider();

    const auto &consumer = provider.getService<ServiceExecutor>();

    std::cout << "work all: " << consumer.workAll() << std::endl;
    std::cout << "single work: " << provider.getService<IWorker>().work();

    return 0;
}
Output#
work all: work A done! work B done! work C done!
single work: work C done!