Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #21553 [DI] Replace container injection by explicit service l…
…ocators (chalasr) This PR was merged into the 3.3-dev branch. Discussion ---------- [DI] Replace container injection by explicit service locators | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #20658 | License | MIT | Doc PR | symfony/symfony-docs#7458 This adds a new `ServiceLocatorArgument` (`!service_locator`) argument type which takes a list of services, meant to be used as a concrete service locator in order to avoid the remaining needs for injecting the container when it's only a matter of dependency lazy-loading. Config: ```yaml App\FooBar: [!service_locator { key1: '@Service1', key2: '@service2' }] ``` ```xml <service class="App\FooBar" public="false"> <argument type="service-locator"> <argument type="service" key="key1" id="service1"/> <argument type="service" key="key2" id="service2"/> </argument> </service> ``` ```php new ServiceLocatorArgument(array('key1' => new Reference('service1'), 'key2' => new Reference('service2')); ``` Usage: ```php $locator->has('key1') // true $locator->has('service1') // false, the defined key must be used $locator->get('key1'); // service1 instance $locator->get('service1'); // exception $locator->has('not-specified') // false $locator->get('not-specified'); // exception ``` We have some concrete use cases in the core where this would be useful (see e.g. SecurityBundle's FirewallMap), same in userland/3rd party code (see related RFC). Commits ------- e7935c0 [DI] Replace container injection by explicit service locators
- Loading branch information
Showing
37 changed files
with
474 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
src/Symfony/Component/DependencyInjection/Argument/ServiceLocatorArgument.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\DependencyInjection\Argument; | ||
|
||
use Symfony\Component\DependencyInjection\Reference; | ||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; | ||
|
||
/** | ||
* Represents a service locator able to lazy load a given range of services. | ||
* | ||
* @author Robin Chalas <robin.chalas@gmail.com> | ||
* | ||
* @experimental in version 3.3 | ||
*/ | ||
class ServiceLocatorArgument implements ArgumentInterface | ||
{ | ||
private $values; | ||
|
||
/** | ||
* @param Reference[] $values An array of references indexed by identifier | ||
*/ | ||
public function __construct(array $values) | ||
{ | ||
$this->setValues($values); | ||
} | ||
|
||
public function getValues() | ||
{ | ||
return $this->values; | ||
} | ||
|
||
public function setValues(array $values) | ||
{ | ||
foreach ($values as $v) { | ||
if (!$v instanceof Reference) { | ||
throw new InvalidArgumentException('Values of a ServiceLocatorArgument must be Reference objects.'); | ||
} | ||
} | ||
|
||
$this->values = $values; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
src/Symfony/Component/DependencyInjection/ServiceLocator.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\DependencyInjection; | ||
|
||
use Psr\Container\ContainerInterface as PsrContainerInterface; | ||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; | ||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; | ||
|
||
/** | ||
* @author Robin Chalas <robin.chalas@gmail.com> | ||
* @author Nicolas Grekas <p@tchwork.com> | ||
* | ||
* @experimental in version 3.3 | ||
*/ | ||
class ServiceLocator implements PsrContainerInterface | ||
{ | ||
private $factories; | ||
private $values = array(); | ||
|
||
/** | ||
* @param callable[] $factories | ||
*/ | ||
public function __construct(array $factories) | ||
{ | ||
$this->factories = $factories; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function has($id) | ||
{ | ||
return isset($this->factories[$id]); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function get($id) | ||
{ | ||
if (!isset($this->factories[$id])) { | ||
throw new ServiceNotFoundException($id, null, null, array_keys($this->factories)); | ||
} | ||
|
||
if (true === $factory = $this->factories[$id]) { | ||
throw new ServiceCircularReferenceException($id, array($id, $id)); | ||
} | ||
|
||
if (false !== $factory) { | ||
$this->factories[$id] = true; | ||
$this->values[$id] = $factory(); | ||
$this->factories[$id] = false; | ||
} | ||
|
||
return $this->values[$id]; | ||
} | ||
|
||
public function __invoke($id) | ||
{ | ||
return isset($this->factories[$id]) ? $this->get($id) : null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.