Array Service Provider
ServiceProviderArray is the ready-made service provider that describes its services with a plain configuration array. For most cases where you want lazy service registration this is all you need — no custom class required.
It implements both ServiceProviderInterface and ServiceProviderClassLookupInterface, so it supports class lookups without instantiation out of the box.
use ClanCats\Container\{
Container,
ServiceProviderArray
};The service configuration array
Each service is a keyed entry describing how to build it:
class(required) — the fully qualified class name.arguments— constructor arguments (@for a dependency,:for a parameter, everything else raw).shared— whether the resolved instance is cached as a singleton. Defaults totruebecause that is what most services want (one connection, one logger, one config). Set it tofalsewhen each consumer needs its own fresh instance.calls— method calls to run after construction, each an array with amethodand itsarguments.
Using it directly
Create an instance, feed it a service map with setServices, then register it.
$provider = new ServiceProviderArray();
$provider->setServices([
'engine' => [
'class' => Engine::class,
'shared' => false,
'calls' => [
['method' => 'setPower', 'arguments' => [315]],
],
],
'producer' => [
'class' => Producer::class,
'arguments' => ['Audi'],
],
]);
$container->register($provider);Set the providers services
Method definition:
public function setServices(array $services): voidArguments
| Data type | Variable name | Comment |
|---|---|---|
| array<string, | array<mixed>> $services |
Using it as a base class
For a fixed set of services it is often cleaner to subclass the provider and override the protected $services property.
use ClanCats\Container\ServiceProviderArray;
class CarServiceProvider extends ServiceProviderArray
{
protected array $services =
[
'car' =>
[
'class' => Car::class,
'arguments' => ['@engine', '@producer'],
],
'engine' =>
[
'class' => Engine::class,
'shared' => false,
'calls' => [
['method' => 'setPower', 'arguments' => [315]],
],
],
'producer' =>
[
'class' => Producer::class,
'arguments' => ['Audi'],
],
];
}$container->register(new CarServiceProvider());
$car = $container->get('car'); // built lazily, on demandHow it resolves
provides() simply returns the keys of the service map.
What services are provided by the service provider
Method definition:
public function provides() : arrayArguments
This method takes no arguments.
Returns
array<string>
resolve() builds a ServiceFactory from the configuration entry via ServiceFactory::fromArray, constructs the service, and reports it as shared unless the entry set shared to false.
Resolve a service with the given name
Method definition:
public function resolve(string $serviceName, Container $container) : arrayArguments
| Data type | Variable name | Comment |
|---|---|---|
| string | $serviceName | |
| Container | $container |
Returns
array{mixed, bool}
Class lookups
Because the provider knows every service's class up front, it can answer class lookups without instantiating anything.
$provider->lookupClassName('engine', $container); // Engine::classAn entry without a class key throws an InvalidServiceException, and an unknown service name throws an UnknownServiceException.
Returns the class name for a given service
Method definition:
public function lookupClassName(string $serviceName, Container $container) : stringArguments
| Data type | Variable name | Comment |
|---|---|---|
| string | $serviceName | |
| Container | $container |
Returns
class-string
