Skip to content

Commit

Permalink
ServiceLocator behaviour modified to be more like 'registry' instead …
Browse files Browse the repository at this point in the history
…of 'lightweight container'
  • Loading branch information
dg committed Apr 30, 2008
1 parent 7dc6524 commit 2d413fb
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 55 deletions.
79 changes: 31 additions & 48 deletions src/DI/ServiceLocator.php
Expand Up @@ -63,48 +63,36 @@ public function __construct(IServiceLocator $parent = NULL)
* @param string optional service name (for factories is not optional)
* @param bool promote to higher level?
* @return void
* @throws ::InvalidArgumentException, Exception
* @throws ::InvalidArgumentException, AmbiguousServiceException
*/
public function addService($service, $type = NULL, $promote = FALSE)
public function addService($service, $name = NULL, $promote = FALSE)
{
if (is_object($service)) {
if ($type === NULL) $type = get_class($service);
if ($name === NULL) $name = get_class($service);

} elseif (is_string($service)) {
if ($type === NULL) $type = $service;
if ($name === NULL) $name = $service;

} elseif (is_callable($service, TRUE)) {
if (empty($type)) {
if (empty($name)) {
throw new /*::*/InvalidArgumentException('Missing service name.');
}

} else {
throw new /*::*/InvalidArgumentException('Service must be class/interface name, object or factory callback.');
}


/**/// fix for namespaced classes/interfaces in PHP < 5.3
if ($a = strrpos($type, ':')) $type = substr($type, $a + 1);/**/

if (class_exists($type)) {
foreach (class_implements($type) as $class) {
$this->registry[strtolower($class)][] = $service;
}

foreach (class_parents($type) as $class) {
$this->registry[strtolower($class)][] = $service;
}
}
if ($a = strrpos($name, ':')) $name = substr($name, $a + 1);/**/

$lType = strtolower($type);
if (!empty($this->registry[$lType])) {
throw new AmbiguousServiceException("Ambiguous service '$type'.");
$lower = strtolower($name);
if (isset($this->registry[$lower]) && is_object($this->registry[$lower])) {
throw new AmbiguousServiceException("Ambiguous service '$name'.");
}
$this->registry[$lType][] = $service;

$this->registry[$lower] = $service;

if ($promote && $this->parent !== NULL) {
$this->parent->addService($service, $type, TRUE);
$this->parent->addService($service, $name, TRUE);
}
}

Expand All @@ -113,16 +101,16 @@ public function addService($service, $type = NULL, $promote = FALSE)
/**
* Removes the specified service type from the service container.
*/
public function removeService($type, $promote = FALSE)
public function removeService($name, $promote = FALSE)
{
if (!is_string($type)) {
throw new /*::*/InvalidArgumentException('Service must be class/interface name.');
if (!is_string($name) || $name === '') {
throw new /*::*/InvalidArgumentException('Service name must be a non-empty string.');
}

// not implemented yet

if ($promote && $this->parent !== NULL) {
$this->parent->removeService($type, TRUE);
$this->parent->removeService($name, TRUE);
}
}

Expand All @@ -131,43 +119,38 @@ public function removeService($type, $promote = FALSE)
/**
* Gets the service object of the specified type.
*/
public function getService($type)
public function getService($name)
{
if (!is_string($type) || $type === '') {
throw new /*::*/InvalidArgumentException('Service must be class/interface name.');
if (!is_string($name) || $name === '') {
throw new /*::*/InvalidArgumentException('Service name must be a non-empty string.');
}

/**/// fix for namespaced classes/interfaces in PHP < 5.3
if ($a = strrpos($type, ':')) $type = substr($type, $a + 1);/**/
if ($a = strrpos($name, ':')) $name = substr($name, $a + 1);/**/

$lType = strtolower($type);
$lower = strtolower($name);

if (isset($this->registry[$lType])) {
if (count($this->registry[$lType]) > 1) {
throw new AmbiguousServiceException("Ambiguous service '$type' resolution.");
}
if (isset($this->registry[$lower])) {
$service = $this->registry[$lower];
if (is_object($service)) {
return $service;

$obj = $this->registry[$lType][0];
if (is_object($obj)) {
return $obj;

} elseif (is_string($obj)) {
} elseif (is_string($service)) {
/**/// fix for namespaced classes/interfaces in PHP < 5.3
if ($a = strrpos($obj, ':')) $obj = substr($obj, $a + 1);/**/

return $this->registry[$lType][0] = new $obj;
if ($a = strrpos($service, ':')) $service = substr($service, $a + 1);/**/
return $this->registry[$lower] = new $service;

} else {
return $this->registry[$lType][0] = call_user_func($obj);
return $this->registry[$lower] = call_user_func($service);
}

} elseif ($this->autoDiscovery) {
if (class_exists($type)) {
return $this->registry[$lType][0] = new $type;
if (class_exists($name)) {
return $this->registry[$lower] = new $name;
}

} elseif ($this->parent !== NULL) {
return $this->parent->getService($type);
return $this->parent->getService($name);
}

return NULL;
Expand Down
5 changes: 2 additions & 3 deletions tests/DI/config1.ini
@@ -1,5 +1,5 @@
key = "."
section = ":"
:key = "."
:section = ":"

; Production site configuration data
[production]
Expand All @@ -19,4 +19,3 @@ database.params.password = devsecret
timeout = 10
display_errors = true
html_errors = no

3 changes: 1 addition & 2 deletions tests/DI/test.ini1.php
Expand Up @@ -2,8 +2,7 @@

<pre>
<?php
require_once '../../Nette/Debug.php';
require_once '../../Nette/Config.php';
require_once '../../Nette/loader.php';

/*use Nette::Config;*/
/*use Nette::Debug;*/
Expand Down
3 changes: 1 addition & 2 deletions tests/DI/test.ini2.php
Expand Up @@ -2,8 +2,7 @@

<pre>
<?php
require_once '../../Nette/Debug.php';
require_once '../../Nette/Config.php';
require_once '../../Nette/loader.php';

/*use Nette::Config;*/
/*use Nette::Debug;*/
Expand Down

0 comments on commit 2d413fb

Please sign in to comment.