Service manager¶
The Service Manager is a service/object locator, tasked with retrieving other objects. It fully compatible with the PSR’s containers - https://www.php-fig.org/psr/psr-11/
Installation¶
Run the following to install this library:
$ composer require esase/tiny-service-manager
Discrete services¶
Some times we don’t need singletons, we need to retrieve a new object instance whenever we get it from the service manager.
<?php
use Tiny\ServiceManager\ServiceManager;
use stdClass;
// the constructor accepts discrete services as a second parameter
$serviceManager = new ServiceManager([], [
// pass a service name and it's factory
'TestService' => function() { // now this is not a shared service
return new stdClass();
}
]);
var_dump($serviceManager->has('TestService')); // prints `true`
$service1 = $serviceManager->get('TestService');
$service2 = $serviceManager->get('TestService');
var_dump($service1 === $service2); // prints `false` they are different
Factories¶
There are two types of factories which you can use for building you objects: Closure
and Class factories
Closure example¶
The closure it’s just an anonymous (or lambda) function which is called for building an object:
<?php
use Tiny\ServiceManager\ServiceManager;
use stdClass;
$serviceManager = new ServiceManager([
TestService::class => function(
ServiceManager $serviceManager,
string $targetClass
) {
return new stdClass();
}
]);
It’s a good practice to use a class name as key for services, TestService::class
in our case.
Also as you can see the service manager always passes two parameters inside factories:
$serviceManager
- it’s just a reference to it self which may be used for retrieving other dependencies.$targetClass
- a class name which we are trying to build.
Class factory example¶
Remember each factory class must include __invoke
method.
<?php
use Tiny\ServiceManager\ServiceManager;
$serviceManager = new ServiceManager([], [
TestService::class => TestServiceFactory::class
]);
class TestServiceFactory
{
public function __invoke(
ServiceManager $serviceManager,
string $targetClass
): TestService {
// we even may inject different services
return new TestService(
$serviceManager->get(OtherService::class)
...
);
}
}
If you don’t need to provide extra dependencies in you service you may use a default factory class, which just creates you service:
<?php
use Tiny\ServiceManager\ServiceManager;
use Tiny\ServiceManager\Factory\InvokableFactory;
$serviceManager = new ServiceManager([], [
TestService::class => InvokableFactory::class
]);
...