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

0.2.0 2026-02-23 18:24 UTC

This package is auto-updated.

Last update: 2026-02-23 18:27:33 UTC


README

Table of Contents

icon inanepain/servicemanager

Factory-driven dependency injection container.

1. Install

Example 1. composer

composer 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 OptionsInterface mapping.

  • 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.