示例#1
0
 /**
  * Create an object using the factory defined in the given binding.
  * 
  * @param Binding $binding
  * @param InjectionPointInterface $point
  * @return object
  */
 protected function createObjectUsingFactory(Binding $binding, InjectionPointInterface $point = NULL)
 {
     $callback = $binding->getTarget();
     if (is_array($callback)) {
         $callback = [$this->get($callback[0]), $callback[1]];
         $ref = new \ReflectionMethod(get_class($callback[0]), $callback[1]);
     } else {
         $ref = new \ReflectionFunction($callback);
     }
     $resolvers = (array) $binding->getResolvers();
     // Special case: inject config of the type to be created into the factory:
     foreach ($ref->getParameters() as $param) {
         if ($this->getParamType($param) === Configuration::class) {
             $resolvers[$param->name] = $this->config->getConfig(str_replace('\\', '.', $binding->getTypeName()));
         }
     }
     $args = $this->populateArguments($ref, 0, $resolvers, $point);
     switch (count($args)) {
         case 0:
             $object = $callback();
             break;
         case 1:
             $object = $callback($args[0]);
             break;
         case 2:
             $object = $callback($args[0], $args[1]);
             break;
         case 3:
             $object = $callback($args[0], $args[1], $args[2]);
             break;
         case 4:
             $object = $callback($args[0], $args[1], $args[2], $args[3]);
             break;
         default:
             $object = call_user_func_array($callback, $args);
     }
     if ($object instanceof ScopedProxyInterface) {
         return $object;
     }
     $object = $this->initialize($object);
     foreach ($binding->getMarkers(SetterInjection::class) as $setter) {
         $this->performSetterInjection($object, $setter);
     }
     $initializers = $binding->getInitializers();
     if (!empty($initializers)) {
         $object = $this->invokeBindingInitializers($binding->getTypeName(), $object, $initializers);
     }
     return $object;
 }
示例#2
0
 /**
  * Compile a setter injector for a binding.
  * 
  * @param Binding $binding
  * @param boolean $wrapClosure
  * @return string
  */
 protected function compileSetterInjector(Binding $binding, $wrapClosure = true)
 {
     $setters = $binding->getMarkers(SetterInjection::class);
     if (empty($setters)) {
         return 'NULL';
     }
     $setterTypeName = $binding->isImplementationBinding() ? $binding->getTarget() : $binding->getTypeName();
     $code = $wrapClosure ? 'function($obj) { ' : '';
     $ref = new \ReflectionClass($setterTypeName);
     foreach ($setters as $setter) {
         foreach ($this->collectSetterMethods($ref, $setter) as $method) {
             $params = $method->getParameters();
             if (empty($params)) {
                 continue;
             }
             $injector = '$obj->' . $method->getName() . '(';
             foreach ($params as $i => $param) {
                 if (NULL === ($paramTypeName = $param->getClass())) {
                     continue 2;
                 }
                 if ($i != 0) {
                     $injector .= ', ';
                 }
                 $nullable = $param->isOptional() ? 'Nullable' : '';
                 $injector .= '$this->get' . $nullable . '(' . var_export($paramTypeName->name, true) . ', new InjectionPoint(';
                 $injector .= 'get_class($obj), ' . var_export($method->getName(), true) . '))';
             }
             $code .= $injector . '); ';
         }
     }
     return $wrapClosure ? $code . '}' : $code;
 }