Exemplo n.º 1
0
 /**
  * Compiles an inline factory binding by creating a replacement method in the DI container.
  * 
  * @param Binding $binding
  * @return string
  */
 protected function compileInlineFactoryBinding(Binding $binding)
 {
     $code = '';
     $num = count($this->methods);
     $ref = new \ReflectionFunction($binding->getTarget());
     $sig = $this->generateReplacementMethodSignature($ref, $num);
     $body = $this->extractClosureCode($ref);
     $this->methods[] = "\t\t" . $sig . " {\n" . $body . "\n\t\t}";
     $resolvers = (array) $binding->getResolvers();
     foreach ($ref->getParameters() as $param) {
         if ($this->getParamType($param) === Configuration::class) {
             $con = "\$this->config->getConfig(" . var_export(str_replace('\\', '.', $binding->getTypeName()), true) . ')';
             $resolvers[$param->name] = new CompiledCodeFragment($con);
         }
     }
     foreach ($ref->getParameters() as $param) {
         if (!$param->isOptional() && InjectionPointInterface::class === $this->getParamType($param)) {
             $code .= "\t\tif(\$point === NULL) {\n";
             $code .= "\t\t\tthrow new ContextLookupException(";
             $code .= var_export(sprintf('Factory for %s requires access to an injection point', $binding->getTypeName()), true);
             $code .= ");\n";
             $code .= "\t\t}\n";
         }
     }
     $call = $this->generateCallCode($binding->getTypeName(), $ref, $num, [], $resolvers);
     $setterInjection = $binding->isMarked(SetterInjection::class);
     $initializers = (array) $binding->getInitializers();
     if (empty($initializers) && !$setterInjection) {
         $code .= "\t\treturn \$this->initialize(" . $call . ");\n";
     } else {
         $code .= "\t\t\$obj = \$this->initialize(" . $call . ");\n";
         if ($setterInjection) {
             $code .= "\t\t" . $this->compileSetterInjector($binding, false) . "\n";
         }
         foreach ($initializers as $initializer) {
             $num = count($this->methods);
             $ref = new \ReflectionFunction($initializer);
             $sig = $this->generateReplacementMethodSignature($ref, $num);
             $body = $this->extractClosureCode($ref);
             $this->methods[] = "\t\t" . $sig . " {\n" . $body . "\n\t\t}";
             $code .= "\t\t\$obj = " . $this->generateCallCode($binding->getTypeName(), $ref, $num, ['$obj']) . " ?: \$obj;\n";
         }
         $code .= "\t\treturn \$obj;\n";
     }
     return $code;
 }