Skip to content

Commit 263acdd

Browse files
committed
[DI] allow service subscribers to return SubscribedService[]
1 parent 43c09ab commit 263acdd

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

src/Symfony/Contracts/Service/Attribute/SubscribedService.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@
1111

1212
namespace Symfony\Contracts\Service\Attribute;
1313

14+
use Symfony\Contracts\Service\ServiceSubscriberInterface;
1415
use Symfony\Contracts\Service\ServiceSubscriberTrait;
1516

1617
/**
18+
* For use as the return value for {@see ServiceSubscriberInterface}.
19+
*
20+
* @example new SubscribedService('http_client', HttpClientInterface::class, false, new Target('githubApi'))
21+
*
1722
* Use with {@see ServiceSubscriberTrait} to mark a method's return type
1823
* as a subscribed service.
1924
*
@@ -22,12 +27,21 @@
2227
#[\Attribute(\Attribute::TARGET_METHOD)]
2328
final class SubscribedService
2429
{
30+
/** @var object[] */
31+
public array $attributes;
32+
2533
/**
26-
* @param string|null $key The key to use for the service
27-
* If null, use "ClassName::methodName"
34+
* @param string|null $key The key to use for the service
35+
* @param class-string|null $type The service class
36+
* @param bool $nullable Whether the service is optional
37+
* @param object|object[] $attributes One or more dependency injection attributes to use
2838
*/
2939
public function __construct(
30-
public ?string $key = null
40+
public ?string $key = null,
41+
public ?string $type = null,
42+
public bool $nullable = false,
43+
array|object $attributes = [],
3144
) {
45+
$this->attributes = \is_array($attributes) ? $attributes : [$attributes];
3246
}
3347
}

src/Symfony/Contracts/Service/ServiceSubscriberInterface.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Contracts\Service;
1313

14+
use Symfony\Contracts\Service\Attribute\SubscribedService;
15+
1416
/**
1517
* A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method.
1618
*
@@ -29,7 +31,8 @@
2931
interface ServiceSubscriberInterface
3032
{
3133
/**
32-
* Returns an array of service types required by such instances, optionally keyed by the service names used internally.
34+
* Returns an array of service types (or {@see SubscribedService} objects) required
35+
* by such instances, optionally keyed by the service names used internally.
3336
*
3437
* For mandatory dependencies:
3538
*
@@ -47,7 +50,13 @@ interface ServiceSubscriberInterface
4750
* * ['?Psr\Log\LoggerInterface'] is a shortcut for
4851
* * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface']
4952
*
50-
* @return string[] The required service types, optionally keyed by service names
53+
* additionally, an array of {@see SubscribedService}'s can be returned:
54+
*
55+
* * [new SubscribedService('logger', Psr\Log\LoggerInterface::class)]
56+
* * [new SubscribedService(type: Psr\Log\LoggerInterface::class, nullable: true)]
57+
* * [new SubscribedService('http_client', HttpClientInterface::class, attributes: new Target('githubApi'))]
58+
*
59+
* @return string[]|SubscribedService[] The required service types, optionally keyed by service names
5160
*/
5261
public static function getSubscribedServices(): array;
5362
}

src/Symfony/Contracts/Service/ServiceSubscriberTrait.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@ public static function getSubscribedServices(): array
5050
throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class));
5151
}
5252

53-
$serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType;
53+
$attribute = $attribute->newInstance();
5454

55-
if ($returnType->allowsNull()) {
56-
$serviceId = '?'.$serviceId;
57-
}
55+
/* @var SubscribedService $attribute */
56+
57+
$attribute->key ??= self::class.'::'.$method->name;
58+
$attribute->type ??= $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType;
59+
$attribute->nullable = $returnType->allowsNull();
5860

59-
$services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId;
61+
$services[] = $attribute;
6062
}
6163

6264
return $services;

0 commit comments

Comments
 (0)