ody / container
dependency injection container for ODY framework
Requires
- php: >=8.3
- psr/container: ^1.1.2
- psr/simple-cache: ^1.0.1
Requires (Dev)
- phpunit/phpunit: ^9.6
This package is auto-updated.
Last update: 2025-03-25 16:43:58 UTC
README
⚠️ IMPORTANT: This repository is automatically generated from the ody repo and is read-only.
Please submit any pull requests or issues to the main ody repo instead.
Container
Overview
The ODY Container is a service container that manages class dependencies and performs dependency injection. Using a container makes it easy to manage and centralize the way objects are created in your application.
Installation
composer require ody/container
Basic Usage
Creating a Container
use Ody\Container\Container; $container = new Container();
Binding
Basic Binding
// Bind an interface to a concrete implementation $container->bind('App\Contracts\UserRepository', 'App\Repositories\DatabaseUserRepository'); // Bind with a closure $container->bind('database', function ($container) { return new PDO('mysql:host=localhost;dbname=myapp', 'username', 'password'); });
Singleton Binding
Singleton bindings only resolve the object once and return the same instance on subsequent calls:
$container->singleton('App\Services\PaymentGateway', function ($container) { return new App\Services\StripePaymentGateway($container->make('config')); });
Instance Binding
You can bind an existing instance into the container:
$config = new Config(['api_key' => 'your-api-key']); $container->instance('config', $config);
Resolving
// Resolve from the container $userRepository = $container->make('App\Contracts\UserRepository'); // Using array access notation $database = $container['database'];
Auto-Resolution
The container can automatically resolve classes with their dependencies:
class UserController { protected $repository; public function __construct(UserRepository $repository) { $this->repository = $repository; } } // The container will automatically resolve the UserRepository dependency $controller = $container->make(UserController::class);
Advanced Features
Contextual Binding
Contextual binding allows you to specify different implementations based on the class that is requesting the dependency:
$container->when(PhotoController::class) ->needs(Filesystem::class) ->give(LocalFilesystem::class); $container->when(VideoController::class) ->needs(Filesystem::class) ->give(CloudFilesystem::class);
Tagged Services
You can tag related bindings and then resolve them all at once:
$container->bind('SpeedReport', function () { return new SpeedReport(); }); $container->bind('MemoryReport', function () { return new MemoryReport(); }); $container->tag(['SpeedReport', 'MemoryReport'], 'reports'); // Resolve all services with the 'reports' tag $reports = $container->tagged('reports');
Extending Resolved Objects
You can extend a resolved object to add additional functionality:
$container->bind('logger', function () { return new FileLogger(); }); $container->extend('logger', function ($logger, $container) { return new LogDecorator($logger); });
Method Invocation with Dependency Injection
The container can call methods with automatic dependency injection:
$result = $container->call([$controller, 'show'], ['id' => 1]); // Using Class@method syntax $result = $container->call('UserController@show', ['id' => 1]);
Working with Swoole Coroutines
When working with Swoole's coroutines, you might need to scope certain bindings to the current coroutine:
// Register a scoped binding $container->scoped('database.connection', function ($container) { return new DbConnection($container->make('config')); }); // Clear scoped instances between requests $container->forgetScopedInstances();
API Reference
Container Methods
Binding
bind($abstract, $concrete = null, $shared = false)
: Register a binding with the containersingleton($abstract, $concrete = null)
: Register a shared bindingscoped($abstract, $concrete = null)
: Register a binding scoped to the current coroutineinstance($abstract, $instance)
: Register an existing instance as sharedextend($abstract, Closure $closure)
: Extend a resolved instancebindIf($abstract, $concrete = null, $shared = false)
: Register a binding if not already registeredsingletonIf($abstract, $concrete = null)
: Register a shared binding if not already registeredscopedIf($abstract, $concrete = null)
: Register a scoped binding if not already registered
Resolving
make($abstract, array $parameters = [])
: Resolve a type from the containerget($id)
: Resolve a type from the container (PSR-11 compatible)build($concrete)
: Instantiate a concrete instance of a classfactory($abstract)
: Get a closure to resolve the given typecall($callback, array $parameters = [], $defaultMethod = null)
: Call a method with dependency injection
Alias and Tagging
alias($abstract, $alias)
: Alias a type to a different nametag($abstracts, $tags)
: Assign tags to bindingstagged($tag)
: Resolve all bindings for a tag
Contextual Binding
when($concrete)
: Define a contextual bindingaddContextualBinding($concrete, $abstract, $implementation)
: Add a contextual binding
Lifecycle Events
resolving($abstract, Closure $callback = null)
: Register a resolving callbackafterResolving($abstract, Closure $callback = null)
: Register an after resolving callbackbeforeResolving($abstract, Closure $callback = null)
: Register a before resolving callback
Container Management
flush()
: Clear all bindings and resolved instancesforgetInstance($abstract)
: Remove a resolved instanceforgetInstances()
: Clear all resolved instancesforgetScopedInstances()
: Clear all scoped instancesbound($abstract)
: Check if a binding existsresolved($abstract)
: Check if a type has been resolvedhas($id)
: Check if a binding exists (PSR-11 compatible)
ContextualBindingBuilder Methods
needs($abstract)
: Define the abstract target that depends on the contextgive($implementation)
: Define the implementation for the contextual bindinggiveTagged($tag)
: Define tagged services to use as the implementationgiveConfig($key, $default = null)
: Define a configuration value to use as the implementation
Exception Handling
The container throws various exceptions in different scenarios:
BindingResolutionException
: Thrown when a concrete cannot be built or resolvedCircularDependencyException
: Thrown when circular dependencies are detectedEntryNotFoundException
: Thrown when a binding is not found (implements PSR-11)
Integration with ODY Framework
The ContainerHelper
class provides utility methods for integrating the container with the ODY framework:
use Ody\Container\Container; use Ody\Container\ContainerHelper; $container = new Container(); $config = require 'config/app.php'; // Configure the application container with basic services $container = ContainerHelper::configureContainer($container, $config); // Register all controllers in a directory ContainerHelper::registerControllers($container, __DIR__ . '/app/Controllers');
License
The ODY Container is open-sourced software licensed under the MIT license.