inanepain / servicemanager
Factory-driven dependency injection container.
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/inanepain/servicemanager
Requires
- php: >=8.4
- inanepain/config: >=0.4.0
- inanepain/stdlib: >=0.8.0
- psr/container: ^2.0
This package is auto-updated.
Last update: 2026-02-23 18:27:33 UTC
README
Table of Contents
inanepain/servicemanager
Factory-driven dependency injection container.
1. Install
Example 1. composercomposer require inanepain/servicemanager
2. Overview
inanepain/servicemanager is a small, factory-driven dependency injection container.
At its core, a ServiceManager is a registry of services identified by a string name. Each service is produced by a factory (a callable).
The factory signature is intentionally simple:
function (\Inane\ServiceManager\ServiceManager $sm): mixed
Passing the ServiceManager to factories enables dependency resolution inside the factory (e.g. $sm→get('config')).
2.1. Lifecycle: get() vs build()
The ServiceManager supports two retrieval modes:
-
get($name)returns a cached instance.-
The first call builds the service via its factory and stores the result.
-
Subsequent calls return the same instance.
-
-
build($name)always returns a new instance.
This makes it easy to mix singleton-style services (via get()) with transient services (via build()).
2.2. Errors
If a service name is not registered, get() and build() throw Inane\ServiceManager\Exception\NotFoundException (implements Psr\Container\NotFoundExceptionInterface) with the message Service '{name}' not found..
2.3. API Summary
-
ServiceManager::createServiceManager(OptionsInterface $services): static-
Convenience factory that registers each entry in an
OptionsInterfacemapping.
-
-
register(string $name, callable $factory): void-
Registers a service factory under the given name.
-
-
get(string $name): mixed-
Returns the cached service instance.
-
-
build(string $name): mixed-
Builds and returns a new service instance.
-
3. Usage
3.1. Quickstart
Register a service with register() and fetch it with get():
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';
use Inane\ServiceManager\ServiceManager;
$sm = new ServiceManager();
$sm→register('now', static fn (ServiceManager $sm) ⇒ new DateTimeImmutable('now'));
$a = $sm→get('now'); $b = $sm→get('now');
var_dump($a === $b);
3.2. Transient services with build()
Use build() when you want a new instance each time:
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';
use Inane\ServiceManager\ServiceManager;
$sm = new ServiceManager();
$sm→register('uuid', static fn (ServiceManager $sm) ⇒ bin2hex(random_bytes(16)));
$a = $sm→build('uuid'); $b = $sm→build('uuid');
var_dump($a !== $b);
3.3. Factories can resolve dependencies
Factories receive the ServiceManager instance, so they can depend on other services:
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';
use Inane\ServiceManager\ServiceManager; use Psr\Log\NullLogger;
$sm = new ServiceManager();
$sm→register('logger', static fn (ServiceManager $sm) ⇒ new NullLogger());
$sm→register('worker', static function (ServiceManager $sm) { $logger = $sm→get('logger');
return new class($logger) {
public function __construct(private object $logger) {}
};
});
$worker = $sm→get('worker');
3.4. Bulk registration with createServiceManager()
If you already have a mapping of service names to factories, you can create and populate a manager in one step.
<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';
use Inane\ServiceManager\ServiceManager; use Inane\Stdlib\Options;
$services = new Options([ 'config' ⇒ static fn (ServiceManager $sm) ⇒ new Options(['env' ⇒ 'dev']), 'answer' ⇒ static fn (ServiceManager $sm) ⇒ 42, ]);
$sm = ServiceManager::createServiceManager($services);
var_dump($sm→get('answer'));
3.5. Missing services
If you call get() or build() with an unregistered name, an Inane\ServiceManager\Exception\NotFoundException (PSR-11 Psr\Container\NotFoundExceptionInterface) is thrown.