Exemplo n.º 1
0
 /**
  * Retrieve a new instance of a class
  *
  * Forces retrieval of a discrete instance of the given class, using the
  * constructor parameters provided.
  *
  * @param mixed $name Class name or service alias
  * @param array $params Parameters to pass to the constructor
  * @param bool $isShared
  * @return object|null
  */
 public function newInstance($name, array $params = array(), $isShared = true)
 {
     // localize dependencies
     $definitions = $this->definitions;
     $instanceManager = $this->instanceManager();
     if ($instanceManager->hasAlias($name)) {
         $class = $instanceManager->getClassFromAlias($name);
         $alias = $name;
     } else {
         $class = $name;
         $alias = null;
     }
     array_push($this->instanceContext, array('NEW', $class, $alias));
     if (!$definitions->hasClass($class)) {
         $aliasMsg = $alias ? '(specified by alias ' . $alias . ') ' : '';
         throw new Exception\ClassNotFoundException('Class ' . $aliasMsg . $class . ' could not be located in provided definitions.');
     }
     $instantiator = $definitions->getInstantiator($class);
     $injectionMethods = $definitions->getMethods($class);
     $supertypeInjectionMethods = array();
     foreach ($definitions->getClassSupertypes($class) as $supertype) {
         $supertypeInjectionMethods[$supertype] = $definitions->getMethods($supertype);
     }
     if ($instantiator === '__construct') {
         $instance = $this->createInstanceViaConstructor($class, $params, $alias);
         if (array_key_exists('__construct', $injectionMethods)) {
             unset($injectionMethods['__construct']);
         }
     } elseif (is_callable($instantiator, false)) {
         $instance = $this->createInstanceViaCallback($instantiator, $params, $alias);
     } else {
         if (is_array($instantiator)) {
             $msg = sprintf('Invalid instantiator: %s::%s() is not callable.', isset($instantiator[0]) ? $instantiator[0] : 'NoClassGiven', isset($instantiator[1]) ? $instantiator[1] : 'NoMethodGiven');
         } else {
             $msg = sprintf('Invalid instantiator of type "%s" for "%s".', gettype($instantiator), $name);
         }
         throw new Exception\RuntimeException($msg);
     }
     if ($isShared) {
         if ($params) {
             $this->instanceManager->addSharedInstanceWithParameters($instance, $name, $params);
         } else {
             $this->instanceManager->addSharedInstance($instance, $name);
         }
     }
     $this->handleInjectDependencies($instance, $class, $injectionMethods, $supertypeInjectionMethods, $params, $alias);
     array_pop($this->instanceContext);
     return $instance;
 }
Exemplo n.º 2
0
Arquivo: Di.php Projeto: ncud/sagalaya
 /**
  * Retrieve a new instance of a class
  *
  * Forces retrieval of a discrete instance of the given class, using the
  * constructor parameters provided.
  *
  * @param mixed $name Class name or service alias
  * @param array $params Parameters to pass to the constructor
  * @param bool $isShared
  * @return object|null
  */
 public function newInstance($name, array $params = array(), $isShared = true)
 {
     // localize dependencies (this also will serve as poka-yoke)
     $definitions = $this->definitions;
     $instanceManager = $this->instanceManager();
     if ($instanceManager->hasAlias($name)) {
         $class = $instanceManager->getClassFromAlias($name);
         $alias = $name;
     } else {
         $class = $name;
         $alias = null;
     }
     array_push($this->instanceContext, array('NEW', $class, $alias));
     if (!$definitions->hasClass($class)) {
         $aliasMsg = $alias ? '(specified by alias ' . $alias . ') ' : '';
         throw new Exception\ClassNotFoundException('Class ' . $aliasMsg . $class . ' could not be located in provided definition.');
     }
     $instantiator = $definitions->getInstantiator($class);
     $injectionMethods = $definitions->getMethods($class);
     if ($instantiator === '__construct') {
         $object = $this->createInstanceViaConstructor($class, $params, $alias);
         if (array_key_exists('__construct', $injectionMethods)) {
             unset($injectionMethods['__construct']);
         }
     } elseif (is_callable($instantiator)) {
         $object = $this->createInstanceViaCallback($instantiator, $params, $alias);
     } else {
         throw new Exception\RuntimeException('Invalid instantiator');
     }
     if ($isShared) {
         if ($params) {
             $this->instanceManager->addSharedInstanceWithParameters($object, $name, $params);
         } else {
             $this->instanceManager->addSharedInstance($object, $name);
         }
     }
     if ($injectionMethods) {
         foreach ($injectionMethods as $injectionMethod => $methodIsRequired) {
             if ($injectionMethod !== '__construct') {
                 $this->handleInjectionMethodForObject($object, $injectionMethod, $params, $alias, $methodIsRequired);
             }
         }
         $instanceConfiguration = $instanceManager->getConfiguration($name);
         if ($instanceConfiguration['injections']) {
             $objectsToInject = array();
             foreach ($instanceConfiguration['injections'] as $classAliasToInject) {
                 $objectsToInject[] = $this->get($classAliasToInject, $params);
             }
             if ($objectsToInject) {
                 // @todo this needs to be optimized
                 foreach ($objectsToInject as $objectToInject) {
                     foreach ($injectionMethods as $injectionMethod => $methodIsRequired) {
                         if ($methodParams = $definitions->getMethodParameters($class, $injectionMethod)) {
                             foreach ($methodParams as $methodParam) {
                                 if ($this->isSubclassOf(get_class($objectToInject), $methodParam[1])) {
                                     $callParams = $this->resolveMethodParameters(get_class($object), $injectionMethod, array($methodParam[0] => $objectToInject), false, $alias, true);
                                     if ($callParams) {
                                         call_user_func_array(array($object, $injectionMethod), $callParams);
                                     }
                                     continue 3;
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     array_pop($this->instanceContext);
     return $object;
 }
Exemplo n.º 3
0
 /**
  * Retrieve a new instance of a class
  *
  * Forces retrieval of a discrete instance of the given class, using the
  * constructor parameters provided.
  *
  * @param mixed $name Class name or service alias
  * @param array $params Parameters to pass to the constructor
  * @param bool $isShared
  * @return object|null
  */
 public function newInstance($name, array $params = array(), $isShared = true)
 {
     // localize dependencies (this also will serve as poka-yoke)
     $definitions = $this->definitions;
     $instanceManager = $this->instanceManager();
     if ($instanceManager->hasAlias($name)) {
         $class = $instanceManager->getClassFromAlias($name);
         $alias = $name;
     } else {
         $class = $name;
         $alias = null;
     }
     array_push($this->instanceContext, array('NEW', $class, $alias));
     if (!$definitions->hasClass($class)) {
         $aliasMsg = $alias ? '(specified by alias ' . $alias . ') ' : '';
         throw new Exception\ClassNotFoundException('Class ' . $aliasMsg . $class . ' could not be located in provided definitions.');
     }
     $instantiator = $definitions->getInstantiator($class);
     $injectionMethods = $definitions->getMethods($class);
     $supertypeInjectionMethods = array();
     foreach ($definitions->getClassSupertypes($class) as $supertype) {
         $supertypeInjectionMethods[$supertype] = $definitions->getMethods($supertype);
     }
     if ($instantiator === '__construct') {
         $instance = $this->createInstanceViaConstructor($class, $params, $alias);
         if (array_key_exists('__construct', $injectionMethods)) {
             unset($injectionMethods['__construct']);
         }
     } elseif (is_callable($instantiator, false)) {
         $instance = $this->createInstanceViaCallback($instantiator, $params, $alias);
     } else {
         if (is_array($instantiator)) {
             $msg = sprintf('Invalid instantiator: %s::%s() is not callable.', isset($instantiator[0]) ? $instantiator[0] : 'NoClassGiven', isset($instantiator[1]) ? $instantiator[1] : 'NoMethodGiven');
         } else {
             $msg = 'Invalid instantiator';
         }
         throw new \RuntimeException($msg);
     }
     if ($isShared) {
         if ($params) {
             $this->instanceManager->addSharedInstanceWithParameters($instance, $name, $params);
         } else {
             $this->instanceManager->addSharedInstance($instance, $name);
         }
     }
     if ($injectionMethods || $supertypeInjectionMethods) {
         foreach ($injectionMethods as $injectionMethod => $methodIsRequired) {
             if ($injectionMethod !== '__construct') {
                 $this->handleInjectionMethodForInstance($instance, $injectionMethod, $params, $alias, $methodIsRequired);
             }
         }
         foreach ($supertypeInjectionMethods as $supertype => $supertypeInjectionMethod) {
             foreach ($supertypeInjectionMethod as $injectionMethod => $methodIsRequired) {
                 if ($injectionMethod !== '__construct') {
                     $this->handleInjectionMethodForInstance($instance, $injectionMethod, $params, $alias, $methodIsRequired, $supertype);
                 }
             }
         }
         $instanceConfiguration = $instanceManager->getConfiguration($name);
         if ($instanceConfiguration['injections']) {
             $objectsToInject = $methodsToCall = array();
             foreach ($instanceConfiguration['injections'] as $injectName => $injectValue) {
                 if (is_int($injectName) && is_string($injectValue)) {
                     $objectsToInject[] = $this->get($injectValue, $params);
                 } elseif (is_string($injectName) && is_array($injectValue)) {
                     if (is_string(key($injectValue))) {
                         $methodsToCall[] = array('method' => $injectName, 'args' => $injectValue);
                     } else {
                         foreach ($injectValue as $methodCallArgs) {
                             $methodsToCall[] = array('method' => $injectName, 'args' => $methodCallArgs);
                         }
                     }
                 } elseif (is_object($injectValue)) {
                     $objectsToInject[] = $injectValue;
                 } elseif (is_int($injectName) && is_array($injectValue)) {
                     // @todo must find method name somehow
                     throw new Exception\RuntimeException('An injection was provided with a keyed index and an array of data, try using' . ' the name of a particular method as a key for your injection data.');
                 }
             }
             if ($objectsToInject) {
                 foreach ($objectsToInject as $objectToInject) {
                     foreach ($injectionMethods as $injectionMethod => $methodIsRequired) {
                         $methodParams = $definitions->getMethodParameters($class, $injectionMethod);
                         if ($methodParams) {
                             foreach ($methodParams as $methodParam) {
                                 if (get_class($objectToInject) == $methodParam[1] || $this->isSubclassOf(get_class($objectToInject), $methodParam[1])) {
                                     $callParams = $this->resolveMethodParameters(get_class($instance), $injectionMethod, array($methodParam[0] => $objectToInject), false, $alias, true);
                                     if ($callParams) {
                                         call_user_func_array(array($instance, $injectionMethod), $callParams);
                                     }
                                     continue 3;
                                 }
                             }
                         }
                     }
                 }
             }
             if ($methodsToCall) {
                 foreach ($methodsToCall as $methodInfo) {
                     $callParams = $this->resolveMethodParameters(get_class($instance), $methodInfo['method'], $methodInfo['args'], false, $alias, true);
                     call_user_func_array(array($instance, $methodInfo['method']), $callParams);
                 }
             }
         }
     }
     array_pop($this->instanceContext);
     return $instance;
 }