ioc.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php namespace Laravel;
  2. class IoC {
  3. /**
  4. * The available IoC containers.
  5. *
  6. * @var array
  7. */
  8. public static $containers = array();
  9. /**
  10. * Bootstrap the default container and register the dependencies.
  11. *
  12. * @param array $dependencies
  13. * @return void
  14. */
  15. public static function bootstrap($dependencies)
  16. {
  17. $container = static::container();
  18. foreach ($dependencies as $key => $value)
  19. {
  20. $container->register($key, $value['resolver'], (isset($value['singleton'])) ? $value['singleton'] : false);
  21. }
  22. }
  23. /**
  24. * Get a container instance.
  25. *
  26. * If no container name is specified, the default container will be returned.
  27. *
  28. * <code>
  29. * // Get the default container instance
  30. * $container = IoC::container();
  31. *
  32. * // Get a specific container instance
  33. * $container = IoC::container('models');
  34. * </code>
  35. *
  36. * @param string $container
  37. * @return Container
  38. */
  39. public static function container($container = 'default')
  40. {
  41. if ( ! array_key_exists($container, static::$containers))
  42. {
  43. static::$containers[$container] = new Container;
  44. }
  45. return static::$containers[$container];
  46. }
  47. /**
  48. * Magic Method for passing methods to the default container.
  49. *
  50. * <code>
  51. * // Resolve an object from the default container
  52. * $user = IoC::resolve('user');
  53. *
  54. * // Equivalent method of resolving using the container method
  55. * $user = IoC::container()->resolve('user');
  56. * </code>
  57. */
  58. public static function __callStatic($method, $parameters)
  59. {
  60. return call_user_func_array(array(static::container(), $method), $parameters);
  61. }
  62. }
  63. class Container {
  64. /**
  65. * The resolved singleton instances.
  66. *
  67. * @var array
  68. */
  69. private $singletons = array();
  70. /**
  71. * The registered dependencies.
  72. *
  73. * @var array
  74. */
  75. private $resolvers = array();
  76. /**
  77. * Register a dependency and its resolver.
  78. *
  79. * The resolver function when the registered dependency is requested.
  80. *
  81. * <code>
  82. * // Register a simple dependency
  83. * $container->register('name', function() { return 'Fred'; });
  84. *
  85. * // Register a dependency as a singleton
  86. * $container->register('name', function() { return new Name; }, true);
  87. * </code>
  88. *
  89. * @param string $name
  90. * @param Closure $resolver
  91. * @return void
  92. */
  93. public function register($name, $resolver, $singleton = false)
  94. {
  95. $this->resolvers[$name] = array('resolver' => $resolver, 'singleton' => $singleton);
  96. }
  97. /**
  98. * Determine if a dependency has been registered in the container.
  99. *
  100. * <code>
  101. * // Determine if the "user" dependency is registered in the container
  102. * $registered = $container->registered('user');
  103. * </code>
  104. *
  105. * @param string $name
  106. * @return bool
  107. */
  108. public function registered($name)
  109. {
  110. return array_key_exists($name, $this->resolvers);
  111. }
  112. /**
  113. * Register a dependency as a singleton.
  114. *
  115. * Singletons will only be instantiated the first time they are resolved. On subsequent
  116. * requests for the object, the original instance will be returned.
  117. *
  118. * <code>
  119. * // Register a dependency as a singleton
  120. * $container->singleton('user', function() { return new User; })
  121. * </code>
  122. *
  123. * @param string $name
  124. * @param Closure $resolver
  125. * @return void
  126. */
  127. public function singleton($name, $resolver)
  128. {
  129. $this->register($name, $resolver, true);
  130. }
  131. /**
  132. * Register an instance as a singleton.
  133. *
  134. * This method allows you to register an already existing object instance with the
  135. * container as a singleton instance.
  136. *
  137. * <code>
  138. * // Register an object instance as a singleton in the container
  139. * $container->instance('user', new User);
  140. * </code>
  141. *
  142. * @param string $name
  143. * @param mixed $instance
  144. * @return void
  145. */
  146. public function instance($name, $instance)
  147. {
  148. $this->singletons[$name] = $instance;
  149. }
  150. /**
  151. * Resolve a dependency.
  152. *
  153. * The dependency's resolver will be called and its result will be returned.
  154. *
  155. * <code>
  156. * // Resolver the "name" dependency
  157. * $name = $container->resolve('name');
  158. * </code>
  159. *
  160. * @param string $name
  161. * @return mixed
  162. */
  163. public function resolve($name)
  164. {
  165. if (array_key_exists($name, $this->singletons)) return $this->singletons[$name];
  166. if ( ! $this->registered($name))
  167. {
  168. throw new \Exception("Error resolving [$name]. No resolver has been registered in the container.");
  169. }
  170. $object = call_user_func($this->resolvers[$name]['resolver'], $this);
  171. if ($this->resolvers[$name]['singleton']) $this->singletons[$name] = $object;
  172. return $object;
  173. }
  174. }