Example #1
0
 /**
  * Resolves a service definition into the actual service object.
  * 
  * @param  Service $service Service definition.
  * @return object
  */
 public function resolve(Service $service)
 {
     // if already instantiated then just return that instance
     if ($service->isSingleton() && ($instance = $service->getInstance())) {
         return $instance;
     }
     // cannot resolve an abstract service
     if ($service->abstract) {
         throw new AbstractServiceException('Could not instantiate abstract service "' . $service->name . '".');
     }
     // if the service is extending any other service then resolve all parent definitions
     $service = $this->resolveHierarchy($service);
     $instance = $this->instantiateService($service);
     // setting the instance already here will help circular reference via setter injection working
     // but only for singleton services
     // $service now might be a clone because of `::resolveHierarchy()` and therefore this instance
     // reference would be lost - so let's get the original definition and update it
     if ($service->isSingleton() && $service->isExtending()) {
         $originalService = $this->container->getDefinition($service->getName());
         $originalService->setSingleton(true);
         $originalService->setInstance($instance);
     } else {
         $service->setInstance($instance);
     }
     // if there are any method calls, then call them
     try {
         foreach ($service->methodCalls as $call) {
             $this->callMethod($service, $call['method'], $call['arguments'], $instance);
         }
     } catch (CircularReferenceException $e) {
         throw $e;
     } catch (Exception $e) {
         throw new InvalidServiceException('Could not instantiate service "' . $service->name . '" because one of its method calls could not be resolved: ' . $e->getMessage(), 0, $e);
     }
     return $instance;
 }