/**
  * Generates a PHP source file for the provided dependency container
  * @param zibo\core\di\DependencyContainer $container
  * @return string
  */
 public static function generatePhp(DependencyContainer $container)
 {
     $output = "<?php\n\n";
     $output .= "/*\n";
     $output .= " * This file is generated by zibo\\core\\di\\io\\CachedDependencyIO.\n";
     $output .= " */\n";
     $output .= "\n";
     $output .= "use zibo\\core\\di\\Dependency;\n";
     $output .= "use zibo\\core\\di\\DependencyCall;\n";
     $output .= "use zibo\\core\\di\\DependencyCallArgument;\n";
     $output .= "use zibo\\core\\di\\DependencyContainer;\n";
     $output .= "\n";
     $output .= '$container' . " = new DependencyContainer();\n";
     $output .= "\n";
     $dependencies = $container->getDependencies();
     foreach ($dependencies as $interface => $interfaceDependencies) {
         foreach ($interfaceDependencies as $dependency) {
             $callIndex = 1;
             $calls = $dependency->getCalls();
             if ($calls) {
                 foreach ($calls as $call) {
                     $argumentIndex = 1;
                     $arguments = $call->getArguments();
                     if ($arguments) {
                         foreach ($arguments as $argument) {
                             $extra = null;
                             $type = $argument->getType();
                             switch ($type) {
                                 case DependencyCallArgument::TYPE_DEPENDENCY:
                                     $extra = $argument->getDependencyId();
                                     break;
                                 case DependencyCallArgument::TYPE_CONFIG:
                                     $extra = $argument->getDefaultValue();
                                     break;
                             }
                             $output .= '$a' . $argumentIndex . ' = new DependencyCallArgument(';
                             $output .= self::getArgumentValue($type) . ', ';
                             $output .= self::getArgumentValue($argument->getValue()) . ', ';
                             $output .= self::getArgumentValue($extra) . ");\n";
                             $argumentIndex++;
                         }
                     }
                     $output .= '$c' . $callIndex . ' = new DependencyCall(';
                     $output .= self::getArgumentValue($call->getMethodName()) . ");\n";
                     for ($i = 1; $i < $argumentIndex; $i++) {
                         $output .= '$c' . $callIndex . '->addArgument($a' . $i . ");\n";
                     }
                     $callIndex++;
                 }
             }
             $constructorArguments = $dependency->getConstructorArguments();
             if ($constructorArguments) {
                 $argumentIndex = 1;
                 foreach ($constructorArguments as $argument) {
                     $output .= '$a' . $argumentIndex . ' = new DependencyCallArgument(';
                     $output .= self::getArgumentValue($argument->getType()) . ', ';
                     $output .= self::getArgumentValue($argument->getValue()) . ', ';
                     $output .= self::getArgumentValue($argument->getDependencyId()) . ");\n";
                     $argumentIndex++;
                 }
                 $output .= '$c' . $callIndex . " = new DependencyCall('__construct');\n";
                 for ($i = 1; $i < $argumentIndex; $i++) {
                     $output .= '$c' . $callIndex . '->addArgument($a' . $i . ");\n";
                 }
                 $callIndex++;
             }
             $output .= '$d = new Dependency(';
             $output .= self::getArgumentValue($dependency->getClassName()) . ', ';
             $output .= self::getArgumentValue($dependency->getId()) . ");\n";
             for ($i = 1; $i < $callIndex; $i++) {
                 $output .= '$d->addCall($c' . $i . ");\n";
             }
             $output .= '$container->addDependency(';
             $output .= self::getArgumentValue($interface) . ', ';
             $output .= '$d);';
             $output .= "\n\n";
         }
     }
     return $output;
 }
 /**
  * @dataProvider providerAddDependencyThrowsExceptionWhenInvalidForProvided
  * @expectedException zibo\ZiboException
  */
 public function testAddDependencyThrowsExceptionWhenInvalidForProvided($for)
 {
     $container = new DependencyContainer();
     $container->addDependency($for, new Dependency('className'));
 }
 public function testGetAll()
 {
     $interface = 'zibo\\core\\di\\TestInterface';
     $token1 = 'test1';
     $token2 = 'test2';
     $id = 'id';
     $construct1 = new DependencyCall('__construct');
     $construct1->addArgument(new DependencyCallArgument('value', $token1));
     $construct2 = new DependencyCall('__construct');
     $construct2->addArgument(new DependencyCallArgument('value', $token2));
     $dependency1 = new Dependency('zibo\\core\\di\\TestObject', $id);
     $dependency1->addCall($construct1);
     $dependency2 = new Dependency('zibo\\core\\di\\TestObject');
     $dependency2->addCall($construct2);
     $container = new DependencyContainer();
     $container->addDependency($interface, $dependency1);
     $container->addDependency($interface, $dependency2);
     $this->di->setContainer($container);
     $expected = array($id => new TestObject($token1), 0 => new TestObject($token2));
     $result = $this->di->getAll($interface);
     $this->assertEquals($expected, $result);
 }
 /**
  * Reads the dependencies from the provided file and adds them to the
  * provided container
  * @param zibo\core\di\DependencyContainer $container
  * @param zibo\library\filesystem\File $file
  * @return null
  */
 private function readDependencies(DependencyContainer $container, File $file)
 {
     $dom = new Document();
     $dom->load($file);
     $dependencyElements = $dom->getElementsByTagName(self::TAG_DEPENDENCY);
     foreach ($dependencyElements as $dependencyElement) {
         $interface = $dependencyElement->getAttribute(self::ATTRIBUTE_INTERFACE);
         $className = $dependencyElement->getAttribute(self::ATTRIBUTE_CLASS);
         $id = $dependencyElement->getAttribute(self::ATTRIBUTE_ID);
         if (!$id) {
             $id = null;
         }
         $dependency = new Dependency($className, $id);
         $this->readCalls($dependency, $dependencyElement);
         $container->addDependency($interface, $dependency);
     }
 }