From 4a9e8742e5711bc0cf9e656c3969ced6fe84fac8 Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Wed, 20 Dec 2023 13:09:40 -0500 Subject: [PATCH] [DependencyInjection] Add `ServiceCollectionInterface` --- composer.json | 4 +-- .../DependencyInjection/CHANGELOG.md | 1 + .../DependencyInjection/ServiceLocator.php | 13 +++++++--- .../Tests/ServiceLocatorTest.php | 11 ++++++++ .../DependencyInjection/composer.json | 2 +- src/Symfony/Contracts/CHANGELOG.md | 5 ++++ src/Symfony/Contracts/Cache/composer.json | 2 +- .../Contracts/Deprecation/composer.json | 2 +- .../Contracts/EventDispatcher/composer.json | 2 +- .../Contracts/HttpClient/composer.json | 2 +- .../Service/ServiceCollectionInterface.php | 26 +++++++++++++++++++ src/Symfony/Contracts/Service/composer.json | 2 +- .../Contracts/Translation/composer.json | 2 +- src/Symfony/Contracts/composer.json | 2 +- 14 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/Symfony/Contracts/Service/ServiceCollectionInterface.php diff --git a/composer.json b/composer.json index 381c2fef9c772..1894d70b6ccfb 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "psr/http-message": "^1.0|^2.0", "psr/link": "^1.1|^2.0", "psr/log": "^1|^2|^3", - "symfony/contracts": "^2.5|^3.0", + "symfony/contracts": "^3.5", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-icu": "~1.0", @@ -206,7 +206,7 @@ "url": "src/Symfony/Contracts", "options": { "versions": { - "symfony/contracts": "3.4.x-dev" + "symfony/contracts": "3.5.x-dev" } } }, diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md index 368705f611ee5..ace4f5056cf8b 100644 --- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md +++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Add argument `$prepend` to `ContainerConfigurator::extension()` to prepend the configuration instead of appending it + * Have `ServiceLocator` implement `ServiceCollectionInterface` 7.0 --- diff --git a/src/Symfony/Component/DependencyInjection/ServiceLocator.php b/src/Symfony/Component/DependencyInjection/ServiceLocator.php index 548b3310829e8..74b03da6a1dbc 100644 --- a/src/Symfony/Component/DependencyInjection/ServiceLocator.php +++ b/src/Symfony/Component/DependencyInjection/ServiceLocator.php @@ -16,8 +16,8 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Contracts\Service\ServiceCollectionInterface; use Symfony\Contracts\Service\ServiceLocatorTrait; -use Symfony\Contracts\Service\ServiceProviderInterface; use Symfony\Contracts\Service\ServiceSubscriberInterface; /** @@ -26,9 +26,9 @@ * * @template-covariant T of mixed * - * @implements ServiceProviderInterface + * @implements ServiceCollectionInterface */ -class ServiceLocator implements ServiceProviderInterface, \Countable +class ServiceLocator implements ServiceCollectionInterface { use ServiceLocatorTrait { get as private doGet; @@ -82,6 +82,13 @@ public function count(): int return \count($this->getProvidedServices()); } + public function getIterator(): \Traversable + { + foreach ($this->getProvidedServices() as $id => $config) { + yield $id => $this->get($id); + } + } + private function createNotFoundException(string $id): NotFoundExceptionInterface { if ($this->loading) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/ServiceLocatorTest.php b/src/Symfony/Component/DependencyInjection/Tests/ServiceLocatorTest.php index 3a73b18271640..2b3ab52b5afd9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ServiceLocatorTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ServiceLocatorTest.php @@ -101,6 +101,17 @@ public function testProvidesServicesInformation() 'baz' => '?string', ]); } + + public function testIsCountableAndIterable() + { + $locator = $this->getServiceLocator([ + 'foo' => fn () => 'bar', + 'bar' => fn () => 'baz', + ]); + + $this->assertCount(2, $locator); + $this->assertSame(['foo' => 'bar', 'bar' => 'baz'], iterator_to_array($locator)); + } } class SomeServiceSubscriber implements ServiceSubscriberInterface diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index d3651f2052a15..b5fda9bdeb990 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -19,7 +19,7 @@ "php": ">=8.2", "psr/container": "^1.1|^2.0", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/service-contracts": "^3.3", + "symfony/service-contracts": "^3.5", "symfony/var-exporter": "^6.4|^7.0" }, "require-dev": { diff --git a/src/Symfony/Contracts/CHANGELOG.md b/src/Symfony/Contracts/CHANGELOG.md index 4044866772d57..02c91564f7032 100644 --- a/src/Symfony/Contracts/CHANGELOG.md +++ b/src/Symfony/Contracts/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +3.5 +--- + + * Add `ServiceCollectionInterface` + 3.4 --- diff --git a/src/Symfony/Contracts/Cache/composer.json b/src/Symfony/Contracts/Cache/composer.json index f80d0b5595b01..fe261d185a936 100644 --- a/src/Symfony/Contracts/Cache/composer.json +++ b/src/Symfony/Contracts/Cache/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/src/Symfony/Contracts/Deprecation/composer.json b/src/Symfony/Contracts/Deprecation/composer.json index c6d02d874966f..ceb6c07961052 100644 --- a/src/Symfony/Contracts/Deprecation/composer.json +++ b/src/Symfony/Contracts/Deprecation/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/src/Symfony/Contracts/EventDispatcher/composer.json b/src/Symfony/Contracts/EventDispatcher/composer.json index 3618d53e973b1..35956eb807fdd 100644 --- a/src/Symfony/Contracts/EventDispatcher/composer.json +++ b/src/Symfony/Contracts/EventDispatcher/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/src/Symfony/Contracts/HttpClient/composer.json b/src/Symfony/Contracts/HttpClient/composer.json index 084d49072a21d..efb146ec12826 100644 --- a/src/Symfony/Contracts/HttpClient/composer.json +++ b/src/Symfony/Contracts/HttpClient/composer.json @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/src/Symfony/Contracts/Service/ServiceCollectionInterface.php b/src/Symfony/Contracts/Service/ServiceCollectionInterface.php new file mode 100644 index 0000000000000..2333139ce783b --- /dev/null +++ b/src/Symfony/Contracts/Service/ServiceCollectionInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * A ServiceProviderInterface that is also countable and iterable. + * + * @author Kevin Bond + * + * @template-covariant T of mixed + * + * @extends ServiceProviderInterface + * @extends \IteratorAggregate + */ +interface ServiceCollectionInterface extends ServiceProviderInterface, \Countable, \IteratorAggregate +{ +} diff --git a/src/Symfony/Contracts/Service/composer.json b/src/Symfony/Contracts/Service/composer.json index 32bb8a316b797..061561c91b7d8 100644 --- a/src/Symfony/Contracts/Service/composer.json +++ b/src/Symfony/Contracts/Service/composer.json @@ -31,7 +31,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/src/Symfony/Contracts/Translation/composer.json b/src/Symfony/Contracts/Translation/composer.json index 213b5cda8b269..181651e0d9a87 100644 --- a/src/Symfony/Contracts/Translation/composer.json +++ b/src/Symfony/Contracts/Translation/composer.json @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/src/Symfony/Contracts/composer.json b/src/Symfony/Contracts/composer.json index e016cb8ee0882..e43cff6f23ea6 100644 --- a/src/Symfony/Contracts/composer.json +++ b/src/Symfony/Contracts/composer.json @@ -45,7 +45,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" } } }