PHPackages                             monkeyscloud/monkeyslegion-di - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. monkeyscloud/monkeyslegion-di

ActiveLibrary[PSR &amp; Standards](/categories/psr-standards)

monkeyscloud/monkeyslegion-di
=============================

Production-ready PSR-11 container for MonkeysLegion — auto-wiring, attributes, compiled container.

1.0.5(2mo ago)01.3k↑250%9MITPHPPHP ^8.4

Since Jul 24Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/MonkeysCloud/MonkeysLegion-Di)[ Packagist](https://packagist.org/packages/monkeyscloud/monkeyslegion-di)[ RSS](/packages/monkeyscloud-monkeyslegion-di/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (3)Versions (9)Used By (9)

MonkeysLegion DI
================

[](#monkeyslegion-di)

A production-ready **PSR-11** dependency injection container for PHP 8.4+ with auto-wiring, PHP attributes, interface binding, and compiled container support.

[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE)

Installation
------------

[](#installation)

```
composer require monkeyscloud/monkeyslegion-di
```

Quick Start
-----------

[](#quick-start)

```
use MonkeysLegion\DI\Container;

$container = new Container([
    LoggerInterface::class => fn() => new FileLogger('/var/log/app.log'),
]);

// Auto-wires dependencies automatically
$service = $container->get(UserService::class);
```

Features
--------

[](#features)

### Auto-Wiring

[](#auto-wiring)

The container resolves constructor dependencies automatically by inspecting type hints — no configuration needed for concrete classes:

```
class UserService {
    public function __construct(
        private UserRepository $repo,
        private LoggerInterface $logger,
    ) {}
}

// Just works — both dependencies are resolved recursively
$service = $container->get(UserService::class);
```

### Factory Definitions

[](#factory-definitions)

Register services with factory closures for full control over instantiation:

```
$container = new Container([
    PDO::class => fn() => new PDO('mysql:host=localhost;dbname=app', 'user', 'pass'),
    CacheInterface::class => fn(ContainerInterface $c) => new RedisCache(
        $c->get(Redis::class),
    ),
]);
```

### Runtime Registration

[](#runtime-registration)

Register or override services at runtime:

```
$container->set('mailer', fn() => new SmtpMailer($config));
$container->set(LoggerInterface::class, new NullLogger());
```

### Interface Binding

[](#interface-binding)

Map abstractions to concrete implementations:

```
$container->bind(LoggerInterface::class, FileLogger::class);
$container->bind(CacheInterface::class, RedisCache::class);

// Now any class depending on LoggerInterface gets FileLogger
$service = $container->get(UserService::class);
```

### PHP 8.4 Attributes

[](#php-84-attributes)

#### `#[Inject]` — Override Parameter Resolution

[](#inject--override-parameter-resolution)

```
class NotificationService {
    public function __construct(
        #[Inject('slack.logger')]
        private LoggerInterface $logger,
    ) {}
}
```

#### `#[Transient]` — Fresh Instance Every Time

[](#transient--fresh-instance-every-time)

```
#[Transient]
class RequestContext {
    public readonly string $id;

    public function __construct() {
        $this->id = uniqid('req_', true);
    }
}

// Each call returns a new instance
$a = $container->get(RequestContext::class);
$b = $container->get(RequestContext::class);
assert($a !== $b);
```

#### `#[Singleton]` — Explicit Singleton (Default Behavior)

[](#singleton--explicit-singleton-default-behavior)

```
#[Singleton]
class DatabaseConnection {
    // Cached after first resolution (this is the default lifecycle,
    // but the attribute makes intent explicit)
}
```

#### `#[Tagged]` — Service Aggregation

[](#tagged--service-aggregation)

```
#[Tagged('event.listener')]
class UserCreatedListener { /* ... */ }

#[Tagged('event.listener')]
class AuditLogListener { /* ... */ }

// Retrieve all tagged services
$listeners = $container->getTagged('event.listener');
```

### Service Tagging (Programmatic)

[](#service-tagging-programmatic)

```
$container->tag(UserCreatedListener::class, 'event.listener');
$container->tag(AuditLogListener::class, ['event.listener', 'loggable']);

$listeners = $container->getTagged('event.listener');
```

### Transient Lifecycle (Programmatic)

[](#transient-lifecycle-programmatic)

```
$container->transient(RequestContext::class);
```

### Builder Pattern

[](#builder-pattern)

Use `ContainerBuilder` for structured setup with providers:

```
use MonkeysLegion\DI\ContainerBuilder;

$builder = new ContainerBuilder();

$builder
    ->addDefinitions([
        PDO::class => fn() => new PDO($dsn, $user, $pass),
    ])
    ->set('app.debug', fn() => true)
    ->bind(LoggerInterface::class, FileLogger::class)
    ->tag(UserCreatedListener::class, 'event.listener')
    ->transient(RequestContext::class);

$container = $builder->build();
```

### Compiled Container (Production)

[](#compiled-container-production)

Pre-compile the container for faster boot times in production:

```
use MonkeysLegion\DI\ContainerBuilder;
use MonkeysLegion\DI\ContainerDumper;

// Build and dump (deploy step)
$builder = new ContainerBuilder();
$builder->addDefinitions([/* ... */]);
$container = $builder->build();

$dumper = new ContainerDumper();
$dumper->dump($container, '/var/cache/compiled_container.php');

// Load in production (fast boot)
$builder = new ContainerBuilder();
$builder
    ->addDefinitions([/* same definitions */])
    ->enableCompilation('/var/cache');

$container = $builder->build(); // Returns CompiledContainer if cache exists
```

### Static Instance &amp; ContainerAware Trait

[](#static-instance--containeraware-trait)

For scenarios where constructor injection is not possible (e.g., legacy code or deep inheritance), the container supports a global static instance and a helper trait.

**1. Bootstrap Setup:**

```
use MonkeysLegion\DI\Container;
use MonkeysLegion\DI\Traits\ContainerAware;

$container = new Container();
// ... logic to add definitions, bindings, etc.

// Set the global instance for both the Container and the Trait
Container::setInstance($container);
```

**2. Using ContainerAware Trait:**

```
class LegacyService {
    use ContainerAware;

    public function doSomething() {
        // Access dependencies without constructor injection
        $db = $this->resolve(Database::class);

        if ($this->has('feature_flag')) {
            // ...
        }
    }
}
```

### Testing Support

[](#testing-support)

```
// Reset cached instances between tests
$container->reset();
```

API Reference
-------------

[](#api-reference)

### `Container`

[](#container)

MethodDescription`setInstance(Container $container): void`Sets the global static instance.`instance(): self`Retrieves the global instance (throws if not set).`resetInstance(): void`Clears the global static instance.`get(string $id): mixed`Resolve a service (PSR-11)`has(string $id): bool`Check if service exists (PSR-11)`set(string $id, callable|object $def): void`Register/override at runtime`bind(string $abstract, string $concrete): void`Map interface → implementation`tag(string $id, string|array $tags): void`Tag a service`getTagged(string $tag): array`Get all services with a tag`transient(string $id): void`Mark as non-singleton`reset(): void`Clear cached instances`getDefinitions(): array`Get registered definitions### `ContainerBuilder`

[](#containerbuilder)

MethodDescription`addDefinitions(array $defs): self`Merge definitions (won't overwrite)`set(string $id, callable|object $def): self`Register single definition`bind(string $abstract, string $concrete): self`Map interface → implementation`tag(string $id, string|array $tags): self`Tag a service`transient(string $id): self`Mark as non-singleton`enableCompilation(string $dir): self`Enable compiled container`build(): Container`Build the container### `ContainerAware` Trait

[](#containeraware-trait)

MethodDescription`resolve(string $id): mixed`Resolves a service from the global container.`has(string $id): bool`Checks if a service exists.`container(): ContainerInterface`Returns the global container instance.### Attributes

[](#attributes)

AttributeTargetDescription`#[Inject('id')]`ParameterOverride auto-wired parameter`#[Singleton]`ClassExplicit singleton (default)`#[Transient]`ClassNew instance per `get()``#[Tagged('tag')]`ClassAuto-register tag (repeatable)Error Handling
--------------

[](#error-handling)

The container throws PSR-11 compliant exceptions:

- **`ServiceNotFoundException`** — service ID not found (`Psr\Container\NotFoundExceptionInterface`)
- **`ServiceResolveException`** — circular dependency or unresolvable parameter (`Psr\Container\ContainerExceptionInterface`)

Requirements
------------

[](#requirements)

- PHP 8.4+
- `psr/container ^2.0`

Testing
-------

[](#testing)

```
composer install
vendor/bin/phpunit --testdox
```

License
-------

[](#license)

MIT

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance88

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 88% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~48 days

Recently: every ~0 days

Total

6

Last Release

60d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/51e4df19377776baa8eafb605d9e7d2374b855c686f552c20d6856e94e3597c3?d=identicon)[yorchperaza](/maintainers/yorchperaza)

---

Top Contributors

[![yorchperaza](https://avatars.githubusercontent.com/u/2913369?v=4)](https://github.com/yorchperaza "yorchperaza (22 commits)")[![Amanar-Marouane](https://avatars.githubusercontent.com/u/155680356?v=4)](https://github.com/Amanar-Marouane "Amanar-Marouane (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/monkeyscloud-monkeyslegion-di/health.svg)

```
[![Health](https://phpackages.com/badges/monkeyscloud-monkeyslegion-di/health.svg)](https://phpackages.com/packages/monkeyscloud-monkeyslegion-di)
```

###  Alternatives

[pimple/pimple

Pimple, a simple Dependency Injection Container

2.7k130.5M1.4k](/packages/pimple-pimple)[league/container

A fast and intuitive dependency injection container.

86387.8M343](/packages/league-container)[php-di/php-di

The dependency injection container for humans

2.8k48.9M994](/packages/php-di-php-di)[phpwatch/simple-container

A fast and minimal PSR-11 compatible Dependency Injection Container with array-syntax and without auto-wiring

1810.1k2](/packages/phpwatch-simple-container)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
