PHPackages                             milpa/container - 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. [Framework](/categories/framework)
4. /
5. milpa/container

ActiveLibrary[Framework](/categories/framework)

milpa/container
===============

Reflection-autowiring PSR-11 dependency injection container for the Milpa PHP framework: lazy singleton resolution, circular-dependency detection with chain reporting, and safe optional retrieval.

v0.1.2(2d ago)098↓27.5%2Apache-2.0PHP &gt;=8.3

Since Jul 7Compare

[ Source](https://github.com/getmilpa/container)[ Packagist](https://packagist.org/packages/milpa/container)[ RSS](/packages/milpa-container/feed)WikiDiscussions Synced today

READMEChangelog (3)Dependencies (7)Versions (4)Used By (2)

 [   ![Milpa](https://raw.githubusercontent.com/getmilpa/core/main/art/lockup/milpa-lockup-v-color-light.svg)  ](https://github.com/getmilpa)

Milpa Container
===============

[](#milpa-container)

> The **reference dependency injection container** for the Milpa PHP framework, built on **`milpa/core`**. It implements `milpa/core`'s `DIContainerInterface` with reflection autowiring, lazy singleton resolution, and circular-dependency detection that reports the full chain — on top of a PSR-11 surface backed by Symfony's `ContainerBuilder`.

[![CI](https://github.com/getmilpa/container/actions/workflows/ci.yml/badge.svg)](https://github.com/getmilpa/container/actions/workflows/ci.yml)[![Packagist](https://camo.githubusercontent.com/04df890411093f53866fea77efd3d039c4143b2766613b6f4fa6f1fcffaa6532/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d696c70612f636f6e7461696e65722e737667)](https://packagist.org/packages/milpa/container)[![PHP](https://camo.githubusercontent.com/ca03f11ea27dac4dedc8ad56a7bdfc4a9ff5feb825055f9d2983616115076607/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d254532253839254135253230382e332d3737376262342e737667)](https://www.php.net/)[![License](https://camo.githubusercontent.com/798509b4df525f56802b56f8096862487f08023e3d7561c68656f8dab10d0d6e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4170616368652d2d322e302d626c75652e737667)](LICENSE)[![Docs](https://camo.githubusercontent.com/c6dc6a3411e15b0ac7cc4583e8e6a8144181caedb82f5d98753353decda06d77/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d4150492532307265666572656e63652d626c75652e737667)](https://getmilpa.github.io/container/)

`milpa/container` is the concrete `DIContainer` behind `milpa/core`'s `Milpa\Interfaces\Di\DIContainerInterface` — the contract every Milpa component codes against. **No product coupling, no service-definition config format of its own**: register services by hand, or let the container find them by reflection.

Install
-------

[](#install)

```
composer require milpa/container
```

What it guarantees, beyond the interface
----------------------------------------

[](#what-it-guarantees-beyond-the-interface)

`DIContainerInterface` is deliberately conservative: it documents auto-resolution of `get()`/`has()` as a **MAY**, not a MUST — a minimal, spec-conformant implementation is allowed to throw/return `false` for anything not explicitly registered via `registerService()`. `resolve()` is the one method whose contract *is* auto-wiring for every implementation.

`DIContainer` exercises that MAY. Concretely, this implementation guarantees:

- **`get()` and `has()` auto-resolve** any existing, non-abstract, non-interface class whose constructor dependencies are themselves resolvable, recursively — not just identifiers registered via `registerService()`.
- **Auto-resolved classes are cached as singletons** on first resolution: later `get()`calls for the same identifier return the same instance, unless `resolve()` was called directly with `$singleton = false`.
- **Circular dependencies are detected and reported with the full chain** — `A` needs `B`needs `A`, directly or transitively, throws `CircularDependencyException` with every class name in the cycle, not just a generic "circular dependency" message.
- **`tryGet()` never throws** — it returns `null` for anything unregistered and unresolvable, instead of propagating `ServiceNotFoundException` or `ContainerResolutionException`.
- **Non-resolvable classes are cached as such** (interfaces, abstract classes, classes with unresolvable constructor parameters), so repeated lookups don't re-run reflection.

If you need one of these guarantees, depend on `DIContainer` (or its documented behavior) directly — `DIContainerInterface` alone does not promise them.

Quick example
-------------

[](#quick-example)

```
use Milpa\Container\DIContainer;

class Logger
{
    public function log(string $message): void
    {
        echo $message . "\n";
    }
}

class Greeter
{
    public function __construct(private Logger $logger)
    {
    }

    public function greet(string $name): void
    {
        $this->logger->log("Hello, {$name}!");
    }
}

$container = new DIContainer();

// Auto-wiring: no registerService() call needed — Greeter's constructor
// dependency (Logger) is resolved recursively.
$greeter = $container->get(Greeter::class);
$greeter->greet('World'); // "Hello, World!"

// get() caches auto-resolved classes as singletons.
$container->get(Greeter::class) === $greeter; // true

// tryGet() never throws — null for anything unregistered/unresolvable.
$container->tryGet('Nonexistent\Service'); // null

// Explicit registration still wins over auto-wiring for the same id.
$container->registerService(Logger::class, new Logger());
```

Circular dependencies fail loudly, with the chain that caused them:

```
class A { public function __construct(public B $b) {} }
class B { public function __construct(public A $a) {} }

$container->get(A::class);
// throws Milpa\Exceptions\CircularDependencyException:
// "Circular dependency detected while resolving: A -> B -> A."
```

What lives where
----------------

[](#what-lives-where)

LayerPackageOwnsContracts`milpa/core``DIContainerInterface` (extends PSR-11 `ContainerInterface`), `ServiceNotFoundException`, `ContainerResolutionException`, `CircularDependencyException` — the seam, not the engine.**Implementation****`milpa/container`** (this package)The concrete `DIContainer`: reflection autowiring, singleton caching, circular-dependency detection, and safe (`tryGet()`) retrieval on top of Symfony's `ContainerBuilder`.Your appyour host / pluginsWiring decisions — which services to register explicitly vs. leave to autowiring, and when to call `compileContainer()`.Requirements
------------

[](#requirements)

- PHP **≥ 8.3**
- [`milpa/core`](https://packagist.org/packages/milpa/core) **^0.3**
- [`psr/container`](https://packagist.org/packages/psr/container) **^2.0**
- [`symfony/dependency-injection`](https://packagist.org/packages/symfony/dependency-injection) **^7.0**

Documentation
-------------

[](#documentation)

**Full API reference: [getmilpa.github.io/container](https://getmilpa.github.io/container/)** — generated straight from the source DocBlocks and dressed with the Milpa design system.

Contributing
------------

[](#contributing)

Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Please report security issues via [SECURITY.md](SECURITY.md), and note that this project follows a [Code of Conduct](CODE_OF_CONDUCT.md).

License
-------

[](#license)

[Apache-2.0](LICENSE) © TeamX Agency.

---

Milpa is designed, built, and maintained by **[TeamX Agency](https://teamx.agency/?utm_source=github&utm_medium=readme&utm_campaign=milpa&utm_content=container)**.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance99

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

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 ~0 days

Total

3

Last Release

2d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1993784?v=4)[rodrigomx](/maintainers/rodrigomx)[@rodrigomx](https://github.com/rodrigomx)

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/milpa-container/health.svg)

```
[![Health](https://phpackages.com/badges/milpa-container/health.svg)](https://phpackages.com/packages/milpa-container)
```

###  Alternatives

[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6942.5M423](/packages/drupal-core-recommended)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M206](/packages/sulu-sulu)[oro/platform

Business Application Platform (BAP)

645143.5k115](/packages/oro-platform)[contao/core-bundle

Contao Open Source CMS

1231.6M2.8k](/packages/contao-core-bundle)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

751291.4k44](/packages/civicrm-civicrm-core)

PHPackages © 2026

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