I'm very new to IoC idea and I'm trying to jump over the Service Locator pattern. I chose the Kangaru implementation. Suppose I want to use Audio and Logger services in different places of my app. What I have now:
#include <kangaru/kangaru.hpp>
#include <iostream>
using namespace std;
struct IAudio {
virtual void playSound(int id) = 0;
};
struct Audio : IAudio {
void playSound(int id) { cout << "Playing " << id << '\n'; }
};
struct IAudioService : kgr::abstract_service<IAudio> {};
struct AudioService : kgr::single_service<Audio>, kgr::overrides<IAudioService> {};
struct ILogger {
virtual void log(const std::string& message) = 0;
};
struct Logger : ILogger {
void log(const std::string& message) { cout << "Log: " << message << '\n'; }
};
struct ILoggerService : kgr::abstract_service<ILogger> {};
struct LoggerService : kgr::single_service<Logger>, kgr::overrides<ILoggerService> {};
struct User {
User(kgr::container& ioc) : ioc_{ioc} {}
kgr::container& ioc_;
void f1() { ioc_.service<IAudioService>().playSound(1); }
void f2() { ioc_.service<ILoggerService>().log("Hello"); }
};
int main()
{
kgr::container ioc;
ioc.emplace<AudioService>();
ioc.emplace<LoggerService>();
User u(ioc);
u.f1();
u.f2();
return 0;
}
If I understand it correctly, at this point it's just a Service Locator, isn't it? But if I have some nested structure, like this:
struct A {
B b;
}
struct B {
C c;
}
struct C {
D d;
}
, it should be composed in some Composition Root, and class A
should be created through IoC-container, which will resolve dependencies automatically. Here will IoC take true advantage, am I right? And I still have to pass IoC-container everywhere, where I need some service. The advantage is passing single parameter for all services against passing multiple.
And one more thing: dependency injection works for free functions in a same way; if I want to use logger in some void f()
I should either pass IoC-container through arguments, or use directly inside - and there is no dependency injection in that case. But if I don't want to clutter parameters list, I have no choice.