8000 Allow interfaces to be type-hinted as well · symfony/symfony@2dbbfbd · GitHub
[go: up one dir, main page]

Skip to content

Commit 2dbbfbd

Browse files
committed
Allow interfaces to be type-hinted as well
1 parent ff1727e commit 2dbbfbd

File tree

6 files changed

+111
-9
lines changed

6 files changed

+111
-9
lines changed

src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
114114
$method = $method[0];
115115
}
116116

117-
if (!\class_exists($messageClass)) {
117+
if (!\class_exists($messageClass) && !\interface_exists($messageClass)) {
118118
$messageClassLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : $r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method);
119119

120120
throw new RuntimeException(sprintf('Invalid handler service "%s": message class "%s" %s does not exist.', $serviceId, $messageClass, $messageClassLocation));

src/Symfony/Component/Messenger/Handler/Locator/ContainerHandlerLocator.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,39 @@ public function __construct(ContainerInterface $container)
3030
public function resolve($message): callable
3131
{
3232
$messageClass = \get_class($message);
33-
$handlerKey = 'handler.'.$messageClass;
3433

35-
if (!$this->container->has($handlerKey)) {
34+
if (null === $handler = $this->resolveFromClass($messageClass)) {
3635
throw new NoHandlerForMessageException(sprintf('No handler for message "%s".', $messageClass));
3736
}
3837

39-
return $this->container->get($handlerKey);
38+
return $handler;
39+
}
40+
41+
private function resolveFromClass($class): ?callable
42+
{
43+
if ($handler = $this->getHandler($class)) {
44+
return $handler;
45+
}
46+
47+
foreach (class_implements($class, false) as $interface) {
48+
if ($handler = $this->getHandler($interface)) {
49+
return $handler;
50+
}
51+
}
52+
53+
foreach (class_parents($class, false) as $parent) {
54+
if ($handler = $this->getHandler($parent)) {
55+
return $handler;
56+
}
57+
}
58+
59+
return null;
60+
}
61+
62+
private function getHandler($class)
63+
{
64+
$handlerKey = 'handler.'.$class;
65+
66+
return $this->container->has($handlerKey) ? $this->container->get($handlerKey) : null;
4067
}
4168
}

src/Symfony/Component/Messenger/Tests/Asynchronous/Middleware/SendMessageMiddlewareTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use Symfony\Component\Messenger\Asynchronous\Routing\SenderLocatorInterface;
1717
use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage;
1818
use Symfony\Component\Messenger\Envelope;
19-
use Symfony\Component\Messenger\Tests\Asynchronous\Routing\ChildDummyMessage;
19+
use Symfony\Component\Messenger\Tests\Fixtures\ChildDummyMessage;
2020
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
2121
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessageInterface;
2222
use Symfony\Component\Messenger\Transport\SenderInterface;

src/Symfony/Component/Messenger/Tests/Asynchronous/Routing/SenderLocatorTest.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\DependencyInjection\Container;
1616
use Symfony\Component\Messenger\Asynchronous\Routing\SenderLocator;
17+
use Symfony\Component\Messenger\Tests\Fixtures\ChildDummyMessage;
1718
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
1819
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessageInterface;
1920
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
@@ -88,7 +89,3 @@ public function testItSupportsAWildcardInsteadOfTheMessageClass()
8889
$this->assertSame($apiSender, $locator->getSenderForMessage(new SecondMessage()));
8990
}
9091
}
91-
92-
class ChildDummyMessage extends DummyMessage
93-
{
94-
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Tests\Fixtures;
13+
14+
class ChildDummyMessage extends DummyMessage
15+
{
16+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Tests\Handler\Locator;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\DependencyInjection\Container;
7+
use Symfony\Component\Messenger\Handler\Locator\ContainerHandlerLocator;
8+
use Symfony\Component\Messenger\Tests\Fixtures\ChildDummyMessage;
9+
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
10+
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessageInterface;
11+
12+
class ContainerHandlerLocatorTest extends TestCase
13+
{
14+
public function testItLocatesHandlerUsingTheMessageClass()
15+
{
16+
$handler = function () {};
17+
18+
$container = new Container();
19+
$container->set('handler.'.DummyMessage::class, $handler);
20+
21+
$locator = new ContainerHandlerLocator($container);
22+
$resolvedHandler = $locator->resolve(new DummyMessage('Hey'));
23+
24+
$this->assertSame($handler, $resolvedHandler);
25+
}
26+
27+
/**
28+
* @expectedException \Symfony\Component\Messenger\Exception\NoHandlerForMessageException
29+
* @expectedExceptionMessage No handler for message "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"
30+
*/
31+
public function testThrowsNoHandlerException()
32+
{
33+
$locator = new ContainerHandlerLocator(new Container());
34+
$locator->resolve(new DummyMessage('Hey'));
35+
}
36+
37+
public function testResolveMessageViaTheirInterface()
38+
{
39+
$handler = function () {};
40+
41+
$container = new Container();
42+
$container->set('handler.'.DummyMessageInterface::class, $handler);
43+
44+
$locator = new ContainerHandlerLocator($container);
45+
$resolvedHandler = $locator->resolve(new DummyMessage('Hey'));
46+
47+
$this->assertSame($handler, $resolvedHandler);
48+
}
49+
50+
public function testResolveMessageViaTheirParentClass()
51+
{
52+
$handler = function () {};
53+
54+
$container = new Container();
55+
$container->set('handler.'.DummyMessage::class, $handler);
56+
57+
$locator = new ContainerHandlerLocator($container);
58+
$resolvedHandler = $locator->resolve(new ChildDummyMessage('Hey'));
59+
60+
$this->assertSame($handler, $resolvedHandler);
61+
}
62+
}

0 commit comments

Comments
 (0)
0