/** * Registers a notification to be sent in the future, when service with name `$targetServiceName` * will be instantiated by the container or immediatelly if its already instantiated. * * Returns `true` if the notification was delivered immediatelly, `false` if not (either couldn't * be delivered immediatelly, or was enqueued for later). * * @param string $senderName Name of the service that sent this notification. * @param string $targetServiceName Name of the service that should receive this notification. * @param string $methodName Name of the method on the target service that should be called. * @param array $arguments [optional] Method arguments. * @return boolean */ public function registerNotification($senderName, $targetServiceName, $methodName, array $arguments = array()) { // check if maybe such service is already registered and instantiated, // then deliver this notification immediatelly try { $serviceDefinition = $this->container->getDefinition($targetServiceName); // $targetServiceName might be an alias, so let's use the real name $targetServiceName = $serviceDefinition->name; if ($serviceDefinition->isInstantiated()) { return $this->deliverNotification($targetServiceName, $serviceDefinition->instance, $senderName, $methodName, $arguments); } } catch (ServiceNotFoundException $e) { } // but if no service was found then add this notification to the list $this->notifications[$targetServiceName][] = array('sender' => $senderName, 'target' => $targetServiceName, 'method' => $methodName, 'arguments' => $arguments); return false; }
/** * Instantiate the service and perform constructor injection if necessary. * * @param Service $service Service definition. * @return object */ protected function instantiateService(Service $service) { $name = $service->name; // if already resolved the definition, then just call the resolved closure factory if (isset($this->instantiateClosuresCache[$name])) { $instantiateClosure = $this->instantiateClosuresCache[$name]; return $instantiateClosure(); } // deal with closure services if ($service instanceof ClosureService) { $serviceClosure = $service->closure; return $serviceClosure($this->container); } // deal with object services if ($service instanceof ObjectService) { return $service->getInstance(); } // deal with factory services if ($service instanceof FactoryService) { try { $factoryServiceName = $this->parametersResolver->resolve($service->factoryService); $factoryServiceDefinition = $this->container->getDefinition($factoryServiceName); $factoryService = $this->container->get($factoryServiceName); return $this->callMethod($factoryServiceDefinition, $service->factoryMethod, $service->factoryArguments, $factoryService); } catch (Exception $e) { throw new InvalidServiceException('Could not instantiate service "' . $name . '" due to: ' . $e->getMessage(), 0, $e); } } // class can be defined as a parameter $class = $this->parametersResolver->resolve($service->class); if (!class_exists($class)) { throw new InvalidServiceException('Could not instantiate service "' . $name . '" because class ' . $class . ' was not found.'); } $instantiateClosure = $this->createInstantiationClosure($class, $service->arguments); // cache this closure $this->instantiateClosuresCache[$name] = $instantiateClosure; // and finally call it return $instantiateClosure(); }