VOOZH about

URL: https://deepwiki.com/hypervel/container/4.3-extenders-aliases-and-method-bindings

⇱ Extenders, Aliases & Method Bindings | hypervel/container | DeepWiki


Loading...
Menu

Extenders, Aliases & Method Bindings

Purpose and Scope

This document covers three advanced container features that provide dynamic service manipulation and indirection capabilities:

  • Extenders: Decorator mechanism for modifying or wrapping resolved services
  • Aliases: Indirection layer allowing multiple names to reference the same service
  • Method Bindings: Custom resolution callbacks for specific method invocations

These features complement the core binding and resolution mechanisms documented in Service Binding and Dependency Resolution. For lifecycle callback hooks that execute during resolution, see Lifecycle Callbacks. For general method invocation with dependency injection, see Method Invocation & Dependency Injection.


Extenders

Overview

Extenders provide a decorator pattern implementation at the container level, allowing services to be modified or wrapped after resolution but before being returned to the caller. Each extender is a closure stored in the $extenders property that receives the resolved instance and returns a potentially modified instance.

Sources: src/Container.php40-45 src/Container.php314-324 src/Container.php632-643

Resolution Flow


Diagram: Extender Application During Service Resolution

Sources: src/Container.php109-132 src/Container.php632-635

Data Structure

The container maintains extenders in the $extenders property:


This is a two-dimensional array where the first key is the abstract type name, and the value is an array of closures to be applied in sequence.

Sources: src/Container.php40-45

Registration

Extenders are registered using the extend() method:

Method SignatureParametersPurpose
extend(string $abstract, Closure $closure): void$abstract: Service identifier
$closure: Decorator function
Register an extender for a service type

The extender closure receives two parameters:

  1. $service - The resolved service instance
  2. $container - The container instance

And must return the (potentially modified) service instance.

Sources: src/Container.php314-324

Resolution Flow


Diagram: Extender Application During Service Resolution

Sources: src/Container.php109-132 src/Container.php632-635

Immediate Application for Resolved Services

When extend() is called on a service that has already been resolved, the extender is applied immediately to the cached instance in $resolvedEntries:


Diagram: Immediate Extender Application

Sources: src/Container.php314-324

Use Cases

Use CaseExample
DecorationWrapping a logger service with additional context
ConfigurationApplying runtime configuration to a service
Event WrappingAdding event dispatch around service method calls
MonitoringInjecting performance monitoring or tracing
TestingSwapping out parts of a service in test environments

Management Methods

MethodPurpose
forgetExtenders(string $abstract): voidRemove all extenders for a given type

Sources: src/Container.php640-643


Aliases

Overview

The alias system provides an indirection layer through the $aliases and $abstractAliases properties that allows multiple identifiers to resolve to the same underlying service. This enables flexibility in service naming and backwards compatibility when service identifiers change.

Sources: src/Container.php27-38 src/Container.php374-383

Data Structures

The container maintains two complementary data structures for alias management:






















PropertyStructurePurpose
$aliases['alias' => 'abstract']Forward lookup: alias to concrete
$abstractAliases['abstract' => ['alias1', 'alias2']]Reverse lookup: concrete to aliases

Sources: src/Container.php27-38

Alias Registration

Aliases are registered using the alias() method:


Diagram: Alias Registration Process

The method prevents self-aliasing to avoid infinite recursion:


Sources: src/Container.php374-383

Alias Resolution

The getAlias() method recursively resolves aliases to their final abstract type:


Diagram: Recursive Alias Resolution in getAlias() Method

This recursive approach supports alias chains: 'A' -> 'B' -> 'C' where 'A' and 'B' both ultimately resolve to 'C'.

Sources: src/Container.php622-627

Integration Points

Alias resolution is integrated into all major container operations:

MethodAlias Integration Point
make()Resolves alias at entry src/Container.php111-113
get()Resolves alias at entry src/Container.php141-143
set()Resolves alias before storing src/Container.php155-157
unbind()Resolves alias before unbinding src/Container.php167-169
remove()Resolves alias before removal src/Container.php179-181
bound()Resolves alias before checking src/Container.php196-198
has()Checks if identifier is alias src/Container.php213
resolved()Resolves alias before checking src/Container.php221-223

Sources: src/Container.php109-227

Alias Query Methods

MethodReturn TypePurpose
isAlias(string $name): boolboolCheck if identifier is an alias
getAlias(string $abstract): stringstringResolve alias to final abstract

Sources: src/Container.php231-234 src/Container.php622-627

Alias Cleanup

When registering an instance, aliases are cleaned up to prevent conflicts:


Diagram: Alias Cleanup in instance() Method

Sources: src/Container.php329-367

Use Cases

Use CaseExample
Interface Bindingalias(LoggerInterface::class, 'logger')
Legacy SupportMaintain old service names during refactoring
Convenience NamesShort names for commonly used services
Multiple FacadesDifferent entry points to the same service

Method Bindings

Overview

Method bindings stored in the $methodBindings property allow registration of custom resolution callbacks for specific method invocations. When Container::call() is used to invoke a method, if a binding exists for that method, the binding closure is executed instead of the default parameter resolution logic.

Sources: src/Container.php20-24 src/Container.php262-296

Data Structure


Method bindings are stored as a flat array with keys in class@method format.

Sources: src/Container.php20-24

Method Identifier Format

Method bindings use the class@method string format:


Diagram: Method Identifier Format Conversion in parseBindMethod()

The parseBindMethod() helper converts both array and string formats to the canonical string format:


Sources: src/Container.php280-287

Registration

MethodParametersPurpose
bindMethod(array|string $method, Closure $callback): void$method: Method identifier
$callback: Resolution closure
Bind custom resolution for a method

The callback closure receives two parameters:

  1. $instance - The object instance the method belongs to
  2. $container - The container instance

Sources: src/Container.php272-275

Invocation Flow

Method bindings integrate with the BoundMethod::call() system:


Diagram: Method Binding Resolution Sequence

Sources: src/Container.php437-440 src/Container.php264-267 src/Container.php292-295

Query Methods

MethodReturn TypePurpose
hasMethodBinding(string $method): boolboolCheck if method has a binding
callMethodBinding(string $method, mixed $instance): mixedmixedExecute the bound closure

Sources: src/Container.php264-267 src/Container.php292-295

Use Cases

Use CaseExample
Custom ValidationOverride parameter resolution for specific methods
Performance OptimizationBypass full DI for known simple cases
TestingInject mock parameters for specific method calls
Legacy SupportAdapt old method signatures to new container
Special ContextProvide context-specific parameters

The refresh() Utility Method

The refresh() method is a convenience utility that combines rebinding() with property injection, allowing automatic updates when a service is rebound.

Method Signature

MethodParametersReturn TypePurpose
refresh(string $abstract, mixed $target, string $method)$abstract: Service to watch
$target: Object to update
$method: Setter method name
mixedRegister automatic property refresh on rebind

Sources: src/Container.php402-407 src/Contracts/Container.php103

Implementation

The refresh() method wraps rebinding() to automatically call a setter method on a target object:


Diagram: refresh() Method Implementation

Sources: src/Container.php402-407

Use Case Example

The refresh() method is particularly useful when an object holds a reference to a container service that may be rebound:

ScenarioWithout refresh()With refresh()
Service reboundManual update requiredAutomatic update via setter
Multiple dependentsUpdate each manuallySingle refresh() call per dependent
TestingMust remember to syncContainer handles synchronization

Integration and Interaction

Feature Interaction Matrix


Diagram: Integration of Extenders, Aliases, and Method Bindings

Sources: src/Container.php109-132 src/Container.php437-440

Common Patterns

Pattern 1: Alias + Extender

Combine aliases with extenders for flexible service decoration:


Diagram: Alias and Extender Interaction

This pattern allows the same extender to apply whether the service is resolved via alias or concrete name because extend() stores extenders by the final abstract name after alias resolution.

Pattern 2: Method Binding + Container Resolution

Method bindings can themselves use the container to resolve dependencies:


Diagram: Method Binding with Container Dependency Resolution

Pattern 3: Alias Chains

Multiple aliases can form resolution chains:

Alias$aliases[$alias]Final Resolution via getAlias()
'log''logger'LoggerInterface::class
'logger'LoggerInterface::classLoggerInterface::class

The getAlias() method recursively resolves through the entire chain.

Sources: src/Container.php622-627


State Management

Cleanup Operations

OperationExtendersAliasesMethod Bindings
dropStaleInstances()Not affectedRemoved for abstractNot affected
flush()Not clearedCleared completelyNot cleared
forgetExtenders()Removed for abstractNot affectedNot affected
removeAbstractAlias()Not affectedRemoved bidirectionallyNot affected

Sources: src/Container.php648-651 src/Container.php672-677 src/Container.php640-643 src/Container.php354-367

Instance Lifecycle Impact


Diagram: Service Lifecycle with Extensions, Aliases, and Bindings

Sources: src/Container.php109-132 src/Container.php314-324 src/Container.php374-383


Summary

This document covered three advanced container features:

  • Extenders provide decorator pattern capabilities, applying transformations to resolved services in sequence
  • Aliases offer an indirection layer with recursive resolution support for multiple names referencing the same service
  • Method Bindings enable custom resolution logic for specific method invocations via Container::call()

These features integrate seamlessly with the core resolution pipeline and lifecycle callbacks, enabling sophisticated dependency injection patterns without modifying service implementations.

Sources: src/Container.php1-738