From f1c2ab78af69d5cfa1db2c244dbf22e0303036f2 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 5 May 2013 12:11:01 +0200 Subject: [PATCH] [DependencyInjection] Add a method map to avoid computing method names from service names --- .../DependencyInjection/Container.php | 58 ++++++++++--------- .../DependencyInjection/Dumper/PhpDumper.php | 14 +++++ .../Tests/Fixtures/php/services10.php | 3 + .../Tests/Fixtures/php/services11.php | 3 + .../Tests/Fixtures/php/services9_compiled.php | 13 +++++ 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 112f2a3e33..50d413b9d2 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -68,6 +68,7 @@ class Container implements IntrospectableContainerInterface protected $parameterBag; protected $services; + protected $methodMap; protected $scopes; protected $scopeChildren; protected $scopedServices; @@ -260,45 +261,50 @@ class Container implements IntrospectableContainerInterface throw new ServiceCircularReferenceException($id, array_keys($this->loading)); } - if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) { - $this->loading[$id] = true; - - try { - $service = $this->$method(); - } catch (\Exception $e) { - unset($this->loading[$id]); - - if (array_key_exists($id, $this->services)) { - unset($this->services[$id]); + if (isset($this->methodMap[$id])) { + $method = $this->methodMap[$id]; + } elseif (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) { + } else { + if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { + if (!$id) { + throw new ServiceNotFoundException($id); } - if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { - return null; + $alternatives = array(); + foreach (array_keys($this->services) as $key) { + $lev = levenshtein($id, $key); + if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) { + $alternatives[] = $key; + } } - throw $e; + throw new ServiceNotFoundException($id, null, null, $alternatives); } + return null; + } + + $this->loading[$id] = true; + + try { + $service = $this->$method(); + } catch (\Exception $e) { unset($this->loading[$id]); - return $service; - } - - if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { - if (!$id) { - throw new ServiceNotFoundException($id); + if (array_key_exists($id, $this->services)) { + unset($this->services[$id]); } - $alternatives = array(); - foreach (array_keys($this->services) as $key) { - $lev = levenshtein($id, $key); - if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) { - $alternatives[] = $key; - } + if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { + return null; } - throw new ServiceNotFoundException($id, null, null, $alternatives); + throw $e; } + + unset($this->loading[$id]); + + return $service; } /** diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 294de23a77..cbd6b2809e 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -779,6 +779,20 @@ EOF; $code .= " \$this->scopeChildren = array();\n"; } + // build method map + $code .= " \$this->methodMap = array(\n"; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + $code .= ' '.var_export($id, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n"; + } + $aliases = $this->container->getAliases(); + ksort($aliases); + foreach ($aliases as $alias => $id) { + $code .= ' '.var_export($alias, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n"; + } + $code .= " );\n"; + $code .= <<scopes = array(); $this->scopeChildren = array(); + $this->methodMap = array( + 'test' => 'getTestService', + ); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services11.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services11.php index 6cf65ee5b0..89856038b2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services11.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services11.php @@ -31,6 +31,9 @@ class ProjectServiceContainer extends Container $this->scopes = array(); $this->scopeChildren = array(); + $this->methodMap = array( + 'foo' => 'getFooService', + ); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 2deea119f4..dde0543148 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -33,6 +33,19 @@ class ProjectServiceContainer extends Container $this->scopes = array(); $this->scopeChildren = array(); + $this->methodMap = array( + 'bar' => 'getBarService', + 'baz' => 'getBazService', + 'depends_on_request' => 'getDependsOnRequestService', + 'factory_service' => 'getFactoryServiceService', + 'foo' => 'getFooService', + 'foo.baz' => 'getFoo_BazService', + 'foo_bar' => 'getFooBarService', + 'foo_with_inline' => 'getFooWithInlineService', + 'method_call1' => 'getMethodCall1Service', + 'request' => 'getRequestService', + 'alias_for_foo' => 'getFooService', + ); } /**