Using Aliases¶
With the use of aliases, one service can be injected through its multiple base classes, also aliases can be chained. In case of injecting multiple aliases, all real services will be fetched.
Warning
Using aliases is resource intensive, especially for injecting transient and multiple services, provider recursively traverses through the aliases chain to find the proper service. Mixing scoped and singleton aliases for the same base type will lead to undefined behavior
Examples/Guides/ServiceAliases¶
#include <SevenBit/DI.hpp>
#include <iostream>
using namespace sb::di;
struct IServiceA
{
virtual std::string actionA() = 0;
virtual ~IServiceA() = default;
};
struct IServiceB
{
virtual std::string actionB() = 0;
virtual ~IServiceB() = default;
};
struct ServiceA : IServiceA
{
std::string actionA() override { return "actionA"; }
};
struct ServiceB : IServiceB
{
std::string actionB() override { return "actionB"; }
};
struct Service final : ServiceA, ServiceB
{
std::string actionA() override { return "actionA from top service"; }
std::string actionB() override { return "actionB from top service"; }
};
class ServiceExecutor
{
IServiceA &_serviceA;
IServiceB &_serviceB;
public:
ServiceExecutor(IServiceA &serviceA, IServiceB &serviceB) : _serviceA(serviceA), _serviceB(serviceB) {}
[[nodiscard]] std::string execute() const
{
return _serviceA.actionA() + ", " + _serviceB.actionB() + " executed.";
}
};
int main()
{
ServiceProvider provider = ServiceCollection{}
.addSingleton<Service>()
.addAlias<ServiceA, Service>()
.addAlias<ServiceB, Service>()
.addAlias<IServiceA, ServiceA>()
.addAlias<IServiceB, ServiceB>()
.addScoped<ServiceExecutor>()
.buildServiceProvider();
const auto &executor = provider.getService<ServiceExecutor>();
std::cout << executor.execute();
return 0;
}
Output¶
actionA from top service, actionB from top service executed.