In order to assist with dependency injection the library features a ServiceProvider concept that can manage the registration and obtaining of services for you. The library features one implementation by default in the form of the InstanceServiceProvider which manages services on a registered instance level.
In order to create a new InstanceServiceProvider you should use the fluent builder accessible through the #builder static factory method contained in the same class:
As shown in the code snippet services can be pre-registered during the building process, however, you can also register them later utilizing the ServiceProvider#register method and its overloads. The #selfService method instructs the ServiceProvider to register itself to its own registry, if this is not something you need you can simply remove the call.
In order to obtain a service from a ServiceProvider you can either use the #get or #getOrThrow (including overloads) method:
The #get and #getOrThrow methods function similarly however the return value of the former is Nullable while the latter will throw an exception if the service is not present in the registry making it NotNull.
In order to check if a certain services is present in the registry the #has method (including overloads) can be used:
For situations like this a string identifier can be provided during the registration and other actions to distinguish between said services. The library internally creates a ServiceIdentifier instance for all services wherever or not they have a string identifier to ensure proper identification.