Multi-Registration¶
A service id can have multiple registrations. GetService<T>() returns the first registration; GetServices<T>() returns all of them. Constructor parameters of type std::vector<Arc<T>> are resolved with the same GetServices semantics.
Registering Multiple Implementations¶
class IPlugin { public: virtual std::string Name() const = 0; };
class PluginA : public IPlugin { public: std::string Name() const override { return "A"; } };
class PluginB : public IPlugin { public: std::string Name() const override { return "B"; } };
class PluginC : public IPlugin { public: std::string Name() const override { return "C"; } };
auto sc = skr::ServiceCollection()
.AddTransient<IPlugin, PluginA>()
.AddTransient<IPlugin, PluginB>()
.AddTransient<IPlugin, PluginC>();
Resolving¶
auto sp = sc.CreateServiceProvider();
auto first = sp->GetService<IPlugin>(); // PluginA
auto all = sp->GetServices<IPlugin>(); // PluginA, PluginB, PluginC
Injecting a Vector¶
A consumer that wants every implementation can declare a std::vector<Arc<T>> constructor parameter:
class PluginHost
{
public:
explicit PluginHost(std::vector<Arc<IPlugin>> plugins) : mPlugins(std::move(plugins)) {}
void List() const { for (const auto& p : mPlugins) std::cout << p->Name() << "\n"; }
private:
std::vector<Arc<IPlugin>> mPlugins;
};
sc.AddTransient<PluginHost>();
auto host = sp->GetService<PluginHost>();
host->List();
Lifetime Notes¶
- Transient: each registration yields a fresh instance.
- Singleton: the first registration wins; subsequent registrations for the same id are still enumerated by
GetServicesbut yield the same cached instance (de-duplicated by pointer). - Scoped: behaves like Singleton within a scope.
A complete example lives in examples/multi_impl/.