/** * @inheritDoc */ public function applyInflections($object) { foreach ($this->inflections as $type => $methods) { if (!$object instanceof $type) { continue; } foreach ($methods as $method => $inflection) { // $inflection may be array of arguments to pass to the method // OR prepared closure to call with the provided object context. if (!is_callable($inflection)) { // Reflect and resolve method arguments. $callback = $this->argumentResolver->resolveArguments($this->argumentResolver->reflectCallable([$type, $method])); // Replace method arguments with provided ones (if any). $arguments = $callback($inflection); // Wrap calling method with closure to avoid reflecting / resolving each time inflection applied. $this->inflections[$type][$method] = $inflection = function () use($method, $arguments) { $this->{$method}(...$arguments); }; } // We have callable inflection ready, so we simply swap the context to provided object and call it. $inflection->call($object); } } return $object; }
/** * Create callable factory with resolved arguments from class name. * * @param string $class * @return Closure * @throws UninstantiableServiceException */ private function createServiceFactoryFromClass(string $class) : Closure { $reflection = new ReflectionClass($class); if (!$reflection->isInstantiable()) { throw new UninstantiableServiceException($class, $this->resolving); } $constructor = $reflection->getConstructor(); $resolve = $constructor && $constructor->getNumberOfParameters() ? $this->argumentResolver->resolveArguments($constructor) : null; return function (array $arguments = []) use($class, $resolve) { $object = $resolve ? new $class(...$resolve($arguments)) : new $class(); return $object; }; }