Services LifeTime#
Service providers can create scoped service providers:
IServiceProvider::Ptr provider = ServiceCollection{}.buildServiceProvider();
IServiceProvider::Ptr scoped = provider->createScope()
Service can be registered as a singleton, scoped, or transient.
Singleton: service provider will create only one instance of this service (accessible via the getService method)
Scoped: service provider will create only one instance of this service for each scope (accessible via the getService method)
Transient: services are always unique, a new instance is provided every time it is requested, and the service provider returns, in this case, std::unique_ptr (accessible via createService method)
Warning
Only transient services can be created using createService method otherwise the method will throw an exception
Only singleton/scoped services can be accessed using the getService method otherwise the method will throw an exception
#include <SevenBit/DI.hpp>
#include <iostream>
#include <memory>
using namespace sb::di;
struct SingletonService
{
};
struct ScopedService
{
};
struct TransientService
{
};
template <class TService, bool Get> auto getOrCreate(IServiceProvider &provider)
{
if constexpr (Get)
{
return &provider.getService<TService>();
}
else
{
return provider.createService<TService>();
}
}
template <class TService, bool Get> void compareServices(IServiceProvider &root, IServiceProvider &scoped)
{
std::cout << "rootProvider \t == rootProvider:\t"
<< (getOrCreate<TService, Get>(root) == getOrCreate<TService, Get>(root)) << std::endl;
std::cout << "rootProvider \t == scopedProvider:\t"
<< (getOrCreate<TService, Get>(root) == getOrCreate<TService, Get>(scoped)) << std::endl;
std::cout << "scopedProvider \t == scopedProvider:\t"
<< (getOrCreate<TService, Get>(scoped) == getOrCreate<TService, Get>(scoped)) << std::endl;
}
int main()
{
IServiceProvider::Ptr rootProvider = ServiceCollection{}
.addSingleton<SingletonService>()
.addScoped<ScopedService>()
.addTransient<TransientService>()
.buildServiceProvider();
// Accessing Services
SingletonService &singleton = rootProvider->getService<SingletonService>();
ScopedService &scoped = rootProvider->getService<ScopedService>();
std::unique_ptr<TransientService> transient = rootProvider->createService<TransientService>();
IServiceProvider::Ptr scopedProvider = rootProvider->createScope();
std::cout << std::endl << "Singletons comparison" << std::endl;
compareServices<SingletonService, true>(*rootProvider, *scopedProvider);
std::cout << std::endl << "Scoped comparison" << std::endl;
compareServices<ScopedService, true>(*rootProvider, *scopedProvider);
std::cout << std::endl << "Transient comparison" << std::endl;
compareServices<TransientService, false>(*rootProvider, *scopedProvider);
return 0;
}
Singletons comparison
rootProvider == rootProvider: 1
rootProvider == scopedProvider: 1
scopedProvider == scopedProvider: 1
Scoped comparison
rootProvider == rootProvider: 1
rootProvider == scopedProvider: 0
scopedProvider == scopedProvider: 1
Transient comparison
rootProvider == rootProvider: 0
rootProvider == scopedProvider: 0
scopedProvider == scopedProvider: 0