Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Di Laravel Package

orno/di

Orno\Di is a lightweight, PSR-11 compatible dependency injection container for PHP. It supports constructor and setter injection, autowiring, lazy service resolution, aliases, and shared instances, making it easy to wire dependencies cleanly in small applications and custom frameworks.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and pull in the container:

composer require orno/di

The entry point is Orno\Di\Container. Instantiate one at your application's composition root (front controller, bootstrap file, or a service provider) and pass it down — avoid reaching for a global.

use Orno\Di\Container;

$container = new Container();

Your first useful case is autowiring a class with typed constructor dependencies. If UserRepository needs a PDO, you register nothing but the PDO and let the container build the rest:

$container->add('PDO', function () {
    return new PDO('mysql:host=localhost;dbname=app', 'user', 'pass');
});

$repo = $container->get('UserRepository'); // resolved by reflection

Where to look first in the repo: src/Orno/Di/Container.php is the whole API surface. Read the add() and get() methods plus the reflection-based resolver before anything else — the README examples cover the happy path, but the resolution logic is where the real behavior (and the surprises) live. Registering an interface-to-concrete binding is the second thing to try:

$container->bind('UserRepositoryInterface', 'UserRepository');

Implementation Patterns

Interface binding at the composition root. Keep every bind() call in one bootstrap or a dedicated ServiceProvider so you can see the whole wiring map at a glance. This is the single highest-value habit with this container — autowiring is invisible, so the explicit bindings are your documentation.

Factory closures for side-effectful construction. Anything that opens a connection, reads config, or needs a runtime argument should be a closure, not a class name:

$container->add('Mailer', function (Container $c) {
    return new Mailer($c->get('Swift_Mailer'), $c->get('config')['from']);
});

The closure receives the container, so you can chain resolutions without hard-coding class names.

Singletons for shared infrastructure. A database connection, an event dispatcher, a logger — register these once and reuse. Check the add() signature for the singleton/shared flag (it differs between versions of this package); if a service is accidentally rebuilt on every get(), you'll see duplicate connections or lost state first.

Service providers for modular apps. Group related bindings into classes that receive the container and register their own services. It keeps bootstrap.php from turning into a wall of add() calls and makes it easy to register only the modules a given request needs.

Constructor injection first, everything else last. This container's autowiring is strongest on constructor type-hints. Reach for setter/method injection or manual get() calls only where a circular or optional dependency forces it. Treat any $container->get() inside a domain class as a smell — it hides a dependency that should be a constructor parameter.

Framework integration. In a legacy or hand-rolled app, resolve your controllers through the container: $container->get($controllerClass) and let autowiring build the dependency tree. This gives you nearly framework-level DI without adopting the framework's container.

Gotchas and Tips

  • Scalar constructor arguments won't autowire. Reflection can't guess a string $dsn or int $timeout. Either pass explicit arguments when registering, or add a factory closure. This is the #1 source of confusing "cannot resolve" exceptions.
  • Unbound interfaces fail at resolution time, not registration time. bind() is declarative; if you forget it, you won't find out until get() is called. Write a smoke test that resolves your top-level services on every build.
  • Circular dependencies are a real risk. Two classes that type-hint each other will loop forever or blow the stack. Break the cycle with a setter injection or a lazy factory rather than fighting the resolver.
  • Reflection is not free. Autowiring reflects on every class it builds. For long-running or high-throughput entry points, prefer explicit closures for hot services and keep the reflection path for controllers and one-off objects.
  • Watch the shared/instance semantics carefully. Determine whether add() returns the same instance on every get() in your installed version. If state is leaking between resolutions — or being needlessly rebuilt — that flag is the first place to look.
  • PSR-11 interoperability needs a shim. This package predates the PSR-11 container interface, so get()/has() may not match the signatures typehinted by newer libraries. Write a thin adapter class implementing Psr\Container\ContainerInterface around it rather than passing the raw container into third-party code.
  • Debugging resolution failures. The exception messages from the resolver are terse. When a class won't build, check in this order: is the class name spelled exactly right (fully qualified), is every interface it hints bound, and does every scalar parameter have an explicit value?
  • Keep the container out of your domain. Injecting Container into services is a service-locator anti-pattern and makes tests need the whole wiring graph. Inject the resolved dependencies instead; use the container only at the edges.
  • Version and PHP compatibility. This is an older, low-traffic package. Pin the version in composer.json, check it runs on your PHP version before building on it, and consider vendoring or forking if you depend on it heavily — the maintenance surface is small and unlikely to change.
  • Extension point: subclassing Container (or wrapping it in a ServiceProvider layer) is the cleanest way to add cross-cutting behavior like lazy proxies or resolution logging without patching the vendor code.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager