/**
* Replaces the factory callback with the given name with the given factory callback.
*
* The new factory callback will receive as first argument the object created by the current factory, and as second
* argument the container.
*
* @since 3.0.0
*
* @param string $name The name of an existing factory callback.
* @param callable $new_factory The new factory callback.
*
* @return static Container instance.
*
* @throws ContainerLockedException if the container is locked.
* @throws ContainerValueNotSetException if there is no value or factory callback with the given name.
* @throws ContainerValueAlreadySetException if there already is a value with the given name.
*/
public function extend($name, callable $new_factory)
{
if ($this->is_locked) {
throw ContainerLockedException::for_name($name, 'extend');
}
if (!array_key_exists($name, $this->factories)) {
throw ContainerValueNotSetException::for_name($name, 'extend');
}
if (array_key_exists($name, $this->values)) {
throw ContainerValueAlreadySetException::for_name($name, 'extend');
}
$current_factory = $this->factories[$name];
$this->factories[$name] = function (Container $container) use($new_factory, $current_factory) {
return $new_factory($current_factory($container), $container);
};
return $this;
}