Source for file ServiceLocator.php
Documentation is available at ServiceLocator.php
6: * @copyright Copyright (c) 2004, 2010 David Grudl
7: * @license http://nettephp.com/license Nette license
8: * @link http://nettephp.com
16: * Service locator pattern implementation.
18: * @copyright Copyright (c) 2004, 2010 David Grudl
23: /** @var IServiceLocator */
26: /** @var array storage for shared objects */
27: private $registry =
array();
29: /** @var array storage for service factories */
30: private $factories =
array();
35: * @param IServiceLocator
39: $this->parent =
$parent;
45: * Adds the specified service to the service container.
46: * @param string service name
47: * @param mixed object, class name or factory callback
48: * @param bool is singleton?
49: * @param array factory options
52: public function addService($name, $service, $singleton =
TRUE, array $options =
NULL)
54: if (!is_string($name) ||
$name ===
'') {
55: throw new InvalidArgumentException("Service name must be a non-empty string, " .
gettype($name) .
" given.");
58: $lower =
strtolower($name);
59: if (isset($this->registry[$lower])) { // only for instantiated services?
64: if (!$singleton ||
$options) {
65: throw new InvalidArgumentException("Service named '$name' is an instantiated object and must therefore be singleton without options.");
67: $this->registry[$lower] =
$service;
71: throw new InvalidArgumentException("Service named '$name' is empty.");
73: $this->factories[$lower] =
array($service, $singleton, $options);
80: * Removes the specified service type from the service container.
86: throw new InvalidArgumentException("Service name must be a non-empty string, " .
gettype($name) .
" given.");
90: unset($this->registry[$lower], $this->factories[$lower]);
96: * Gets the service object of the specified type.
97: * @param string service name
98: * @param array options in case service is not singleton
103: if (!is_string($name) ||
$name ===
'') {
104: throw new InvalidArgumentException("Service name must be a non-empty string, " .
gettype($name) .
" given.");
109: if (isset($this->registry[$lower])) { // instantiated singleton
111: throw new InvalidArgumentException("Service named '$name' is singleton and therefore can not have options.");
113: return $this->registry[$lower];
115: } elseif (isset($this->factories[$lower])) {
116: list($factory, $singleton, $defOptions) =
$this->factories[$lower];
118: if ($singleton &&
$options) {
119: throw new InvalidArgumentException("Service named '$name' is singleton and therefore can not have options.");
121: } elseif ($defOptions) {
122: $options =
$options ?
$options +
$defOptions :
$defOptions;
130: $service =
new $factory;
132: $service->setOptions($options); // TODO: better!
135: } else { // factory callback
137: if (!$factory->isCallable()) {
140: $service =
$factory->invoke($options);
147: $this->registry[$lower] =
$service;
148: unset($this->factories[$lower]);
153: if ($this->parent !==
NULL) {
164: * Exists the service?
165: * @param string service name
166: * @param bool must be created yet?
172: throw new InvalidArgumentException("Service name must be a non-empty string, " .
gettype($name) .
" given.");
176: return isset($this->registry[$lower]) ||
(!$created &&
isset($this->factories[$lower])) ||
($this->parent !==
NULL &&
$this->parent->hasService($name, $created));
182: * Returns the parent container if any.
183: * @return IServiceLocator|NULL
187: return $this->parent;
195: * Ambiguous service resolution exception.
197: * @copyright Copyright (c) 2004, 2010 David Grudl