milpa/container
Composer 安装命令:
composer require 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.
README 文档
README
Milpa Container
The reference dependency injection container for the Milpa PHP framework, built on
milpa/core. It implementsmilpa/core'sDIContainerInterfacewith reflection autowiring, lazy singleton resolution, and circular-dependency detection that reports the full chain — on top of a PSR-11 surface backed by Symfony'sContainerBuilder.
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
composer require milpa/container
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()andhas()auto-resolve any existing, non-abstract, non-interface class whose constructor dependencies are themselves resolvable, recursively — not just identifiers registered viaregisterService().- Auto-resolved classes are cached as singletons on first resolution: later
get()calls for the same identifier return the same instance, unlessresolve()was called directly with$singleton = false. - Circular dependencies are detected and reported with the full chain —
AneedsBneedsA, directly or transitively, throwsCircularDependencyExceptionwith every class name in the cycle, not just a generic "circular dependency" message. tryGet()never throws — it returnsnullfor anything unregistered and unresolvable, instead of propagatingServiceNotFoundExceptionorContainerResolutionException.- 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
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
| Layer | Package | Owns |
|---|---|---|
| Contracts | 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 app | your host / plugins | Wiring decisions — which services to register explicitly vs. leave to autowiring, and when to call compileContainer(). |
Requirements
- PHP ≥ 8.3
milpa/core^0.3psr/container^2.0symfony/dependency-injection^7.0
Documentation
Full API reference: getmilpa.github.io/container — generated straight from the source DocBlocks and dressed with the Milpa design system.
Contributing
Contributions are welcome — see CONTRIBUTING.md. Please report security issues via SECURITY.md, and note that this project follows a Code of Conduct.
License
Apache-2.0 © TeamX Agency.
Milpa is designed, built, and maintained by TeamX Agency.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: Apache-2.0
- 更新时间: 2026-07-07