feature #23915 [DI] Allow get available services from service locator (Koc)

This PR was merged into the 3.4 branch.

Discussion
----------

[DI] Allow get available services from service locator

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

<!--
- Bug fixes must be submitted against the lowest branch where they apply
  (lowest branches are regularly merged to upper ones so they get the fixes too).
- Features and deprecations must be submitted against the 3.4,
  legacy code removals go to the master branch.
- Please fill in this template according to the PR you're about to submit.
- Replace this comment by a description of what your PR is solving.
-->

Sometimes we are using service locators and throw context specific exceptions if service not found inside it. Would be nice inform user about available services in our custom exception, like:

```php
try {
    return $this->transports->get($transport);
} catch (NotFoundExceptionInterface $e) {
    $availableTransports = method_exists($e, 'getAlternatives') ? $e->getAlternatives() : [];

    throw TransportNotFoundException::create($transport, $availableTransports, $e);
}
```

Commits
-------

4993b1c14c Allow to get alternatives when ServiceNotFoundException occurs.
This commit is contained in:
Fabien Potencier 2017-08-18 14:05:45 +02:00
commit 50fe6a3c76
2 changed files with 16 additions and 2 deletions

View File

@ -22,6 +22,7 @@ class ServiceNotFoundException extends InvalidArgumentException implements NotFo
{
private $id;
private $sourceId;
private $alternatives;
public function __construct($id, $sourceId = null, \Exception $previous = null, array $alternatives = array())
{
@ -44,6 +45,7 @@ class ServiceNotFoundException extends InvalidArgumentException implements NotFo
$this->id = $id;
$this->sourceId = $sourceId;
$this->alternatives = $alternatives;
}
public function getId()
@ -55,4 +57,9 @@ class ServiceNotFoundException extends InvalidArgumentException implements NotFo
{
return $this->sourceId;
}
public function getAlternatives()
{
return $this->alternatives;
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\ServiceLocator;
class ServiceLocatorTest extends TestCase
@ -58,7 +59,7 @@ class ServiceLocatorTest extends TestCase
/**
* @expectedException \Psr\Container\NotFoundExceptionInterface
* @expectedExceptionMessage You have requested a non-existent service "dummy"
* @expectedExceptionMessage You have requested a non-existent service "dummy". Did you mean one of these: "foo", "bar"?
*/
public function testGetThrowsOnUndefinedService()
{
@ -67,7 +68,13 @@ class ServiceLocatorTest extends TestCase
'bar' => function () { return 'baz'; },
));
$locator->get('dummy');
try {
$locator->get('dummy');
} catch (ServiceNotFoundException $e) {
$this->assertSame(array('foo', 'bar'), $e->getAlternatives());
throw $e;
}
}
public function testInvoke()