Packages

  • Nette
    • Application
      • Application\Diagnostics
      • Application\Responses
      • Application\Routers
      • Application\UI
    • Caching
      • Caching\Storages
    • ComponentModel
    • Config
    • Database
      • Database\Diagnostics
      • Database\Drivers
      • Database\Reflection
      • Database\Table
    • DI
    • Diagnostics
    • Forms
      • Forms\Controls
      • Forms\Rendering
    • Http
    • Iterators
    • Latte
      • Latte\Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • None
  • PHP

Classes

  • DIContainer
  • DIContainerBuilder
  • ServiceBuilder

Interfaces

  • IDIContainer
  • IServiceBuilder

Exceptions

  • AmbiguousServiceException
  • MissingServiceException
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  *
  6:  * Copyright (c) 2004, 2011 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  * @package Nette\DI
 11:  */
 12: 
 13: 
 14: 
 15: /**
 16:  * Basic container builder.
 17:  *
 18:  * @author     David Grudl
 19:  * @package Nette\DI
 20:  */
 21: class DIContainerBuilder extends Object
 22: {
 23: 
 24:     /**
 25:      * Adds new services from list of definitions. Expands %param% and @service values.
 26:      * Format:
 27:      *   serviceName => array(
 28:      *      class => 'ClassName' or factory => 'Factory::create'
 29:      *      arguments => array(...)
 30:      *      methods => array(
 31:      *         array(methodName, array(...))
 32:      *         ...
 33:      *      )
 34:      *      tags => array(...)
 35:      *      alias => 'Service'
 36:      *   )
 37:      */
 38:     public function addDefinitions(IDIContainer $container, array $definitions)
 39:     {
 40:         foreach ($definitions as $name => $definition) {
 41:             if (is_scalar($definition)) {
 42:                 if (substr($definition, 0, 1) === '@') {
 43:                     $definition = array('alias' => substr($definition, 1));
 44:                 } else {
 45:                     $definition = array('class' => $definition);
 46:                 }
 47:             }
 48: 
 49:             $arguments = isset($definition['arguments']) ? $definition['arguments'] : array();
 50:             $expander = create_function('&$val', 'extract(NCFix::$vars['.NCFix::uses(array('container'=>$container)).'], EXTR_REFS);
 51:                 if (substr($val, 0, 1) === \'@\') {
 52:                     $val = $container->getService(substr($val, 1));
 53:                 } elseif (is_string($val)) {
 54:                     $val = Strings::expand($val, $container->params);
 55:                 }
 56:             ');
 57: 
 58:             if (isset($definition['class']) || isset($definition['factory'])) {
 59:                 if (isset($definition['class'])) {
 60:                     $class = $definition['class'];
 61:                 } else {
 62:                     $class = NULL;
 63:                     array_unshift($arguments, $definition['factory']);
 64:                 }
 65:                 $methods = isset($definition['methods']) ? $definition['methods'] : array();
 66:                 $factory = create_function('$container', 'extract(NCFix::$vars['.NCFix::uses(array('class'=>$class,'arguments'=> $arguments,'methods'=> $methods,'expander'=> $expander)).'], EXTR_REFS);
 67:                     array_walk_recursive($arguments, $expander);
 68:                     if ($class) {
 69:                         $class = Strings::expand($class, $container->params);
 70:                         if ($arguments) {
 71:                             $service = ClassReflection::from($class)->newInstanceArgs($arguments);
 72:                         } else {
 73:                             $service = new $class;
 74:                         }
 75:                     } else {
 76:                         $factory = $arguments[0]; $arguments[0] = $container;
 77:                         $service = call_user_func_array($factory, $arguments);
 78:                     }
 79: 
 80:                     array_walk_recursive($methods, $expander);
 81:                     foreach ($methods as $method) {
 82:                         call_user_func_array(array($service, $method[0]), isset($method[1]) ? $method[1] : array());
 83:                     }
 84: 
 85:                     return $service;
 86:                 ');
 87: 
 88:             } elseif (isset($definition['alias'])) {
 89:                 $factory = create_function('$container', 'extract(NCFix::$vars['.NCFix::uses(array('definition'=>$definition)).'], EXTR_REFS);
 90:                     return $container->getService($definition[\'alias\']);
 91:                 ');
 92:             } else {
 93:                 throw new InvalidStateException("The definition of service '$name' is missing factory method.");
 94:             }
 95: 
 96:             if (isset($definition['tags'])) {
 97:                 $tags = (array) $definition['tags'];
 98:                 array_walk_recursive($tags, $expander);
 99:             } else {
100:                 $tags = NULL;
101:             }
102:             $container->addService($name, $factory, $tags);
103:         }
104:     }
105: 
106: 
107: 
108:     public function generateCode(array $definitions)
109:     {
110:         $code = '';
111:         foreach ($definitions as $name => $definition) {
112:             $name = $this->varExport($name);
113:             if (is_scalar($definition)) {
114:                 if (substr($definition, 0, 1) === '@') {
115:                     $definition = array('alias' => substr($definition, 1));
116:                 } else {
117:                     $factory = $this->varExport($definition);
118:                     $code .= "\$container->addService($name, $factory);\n\n";
119:                     continue;
120:                 }
121:             }
122: 
123:             if (isset($definition['class']) || isset($definition['factory'])) {
124:                 $arguments = $this->argsExport(isset($definition['arguments']) ? $definition['arguments'] : array());
125:                 $factory = "function(\$container) {\n\t";
126:                 $factory .= isset($definition['class'])
127:                     ? '$class = ' . $this->argsExport(array($definition['class'])) . '; $service = new $class(' . $arguments . ");\n"
128:                     : "\$service = call_user_func(\n\t\t" . $this->argsExport(array($definition['factory']))
129:                         . ",\n\t\t\$container" . ($arguments ? ",\n\t\t$arguments" : '') . "\n\t);\n";
130: 
131:                 if (isset($definition['methods'])) {
132:                     foreach ($definition['methods'] as $method) {
133:                         $args = isset($method[1]) ? $this->argsExport($method[1]) : '';
134:                         $factory .= "\t\$service->$method[0]($args);\n";
135:                     }
136:                 }
137:                 $factory .= "\treturn \$service;\n}";
138: 
139:             } elseif (isset($definition['alias'])) {
140:                 $factory = $this->varExport($definition['alias']);
141:                 $factory = "function(\$container) {\n\treturn \$container->getService($factory);\n}";
142:             } else {
143:                 throw new InvalidStateException("The definition of service '$name' is missing factory method.");
144:             }
145: 
146:             $tags = isset($definition['tags']) ? $this->argsExport(array($definition['tags'])) : 'NULL';
147:             $code .= "\$container->addService($name, $factory, $tags);\n\n";
148:         }
149:         return $code;
150:     }
151: 
152: 
153: 
154:     private function argsExport($args)
155:     {
156:         $args = implode(', ', array_map(array($this, 'varExport'), $args));
157:         $args = preg_replace("#(?<!\\\)'@(\w+)'#", '\$container->getService(\'$1\')', $args);
158:         $args = preg_replace("#(?<!\\\)'%([\w-]+)%'#", '\$container->params[\'$1\']', $args);
159:         $args = preg_replace("#(?<!\\\)'(?:[^'\\\]|\\\.)*%(?:[^'\\\]|\\\.)*'#", 'Strings::expand($0, \$container->params)', $args);
160:         return $args;
161:     }
162: 
163: 
164: 
165:     private function varExport($arg)
166:     {
167:         return preg_replace('#\n *#', ' ', var_export($arg, TRUE));
168:     }
169: 
170: }
171: 
Nette Framework 2.0beta1 (for PHP 5.2) API API documentation generated by ApiGen 2.3.0