/** * Call a method on a service. * * @param Service $service Service to call a method on. * @param string $methodName Name of the method to call on the service. * @param array $arguments [optional] Arguments to call the method with. Default: `array()`. * @param object $instance [optional] Service object instance. Should be passed for all non-singleton services. * @return mixed * * @throws RuntimeException When trying to call a method on a service that hasn't been instantiated yet. */ public function callMethod(Service $service, $methodName, array $arguments = array(), $instance = null) { if ($instance === null && !$service->isInstantiated()) { throw new RuntimeException('Cannot call a method of a service that has not been instantiated yet, when trying to call "::' . $methodName . '" on "' . $service->name . '".'); } $instance = $instance ? $instance : $service->getInstance(); $arguments = $this->argumentsResolver->resolve($arguments); switch (count($arguments)) { case 0: $result = $instance->{$methodName}(); break; case 1: $result = $instance->{$methodName}($arguments[0]); break; case 2: $result = $instance->{$methodName}($arguments[0], $arguments[1]); break; case 3: $result = $instance->{$methodName}($arguments[0], $arguments[1], $arguments[2]); break; case 4: $result = $instance->{$methodName}($arguments[0], $arguments[1], $arguments[2], $arguments[3]); break; case 5: $result = $instance->{$methodName}($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]); break; default: $result = call_user_func_array(array($instance, $methodName), $arguments); } return $result; }