Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ The bundle will try to detect the message itself
by analyzing the methods of the handler and creating instances of the message objects.
But don't worry about performance because this will happen on compiling.

> **Important:** Automatic message detection can only detect handlers where either
> the message implements `Prooph\Common\Messaging\HasMessageName` or the
> name of the method is `__invoke`. In both cases the object must be a non abstract class.

> **Hint:** If you rely on automatic message detection and your handler handles multiple messages of the same message bus,
> you need to tag the handler just once.

Expand Down
6 changes: 5 additions & 1 deletion src/DependencyInjection/Compiler/RoutePass.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class RoutePass implements CompilerPassInterface
{
private static function detectMessageName(ReflectionClass $messageReflection): ?string
{
if (! $messageReflection->implementsInterface(HasMessageName::class)) {
return $messageReflection->getName();
}
$instance = $messageReflection->newInstanceWithoutConstructor(); /* @var $instance HasMessageName */
if ($messageReflection->hasMethod('init')) {
$init = $messageReflection->getMethod('init');
Expand Down Expand Up @@ -111,7 +114,8 @@ private function recognizeMessageNames(
function (ReflectionMethod $method) {
return ($method->getNumberOfRequiredParameters() === 1 || $method->getNumberOfRequiredParameters() === 2)
&& $method->getParameters()[0]->getClass()
&& $method->getParameters()[0]->getClass()->implementsInterface(HasMessageName::class)
&& ($method->getParameters()[0]->getClass()->implementsInterface(HasMessageName::class)
|| $method->getName() === '__invoke')
&& ! ($method->getParameters()[0]->getClass()->isInterface()
|| $method->getParameters()[0]->getClass()->isAbstract()
|| $method->getParameters()[0]->getClass()->isTrait());
Expand Down
21 changes: 21 additions & 0 deletions test/DependencyInjection/AbstractServiceBusExtensionTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\AcmeRegisterUserCommand;
use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\AcmeRegisterUserHandler;
use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\AcmeUserWasRegisteredEvent;
use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForPopoCommand;
use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandWithPrivateConstructor;
use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\MockPlugin;
use ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\PopoCommand;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
Expand Down Expand Up @@ -357,6 +359,25 @@ public function it_adds_command_bus_routes_based_on_tags_with_automatic_message_
$commandBus->dispatch(CommandWithPrivateConstructor::create());
}

/**
* @test
*/
public function it_supports_automatic_message_detection_with_popo_messages_and_invokable_handlers()
{
$container = $this->loadContainer('command_bus_with_tags', new PluginsPass(), new RoutePass());

/* @var $commandBus CommandBus */
$commandBus = $container->get('prooph_service_bus.main_command_bus');

/** @var CommandHandlerForPopoCommand $mockHandler */
$mockHandler = $container->get(CommandHandlerForPopoCommand::class);
$command = new PopoCommand();

$commandBus->dispatch($command);

self::assertSame($command, $mockHandler->lastCommand);
}

/**
* @test
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model;

final class CommandHandlerForPopoCommand
{
/** @var PopoCommand|null */
public $lastCommand;

public function __invoke(PopoCommand $command)
{
$this->lastCommand = $command;
}

/**
* Do not take notice of this method.
* It is necessary to run the tests against prooph/service-bus:6.0.0
* @see https://github.com/prooph/service-bus/pull/159
*/
public function handle(): void
{
}
}
9 changes: 9 additions & 0 deletions test/DependencyInjection/Fixture/Model/PopoCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model;

final class PopoCommand
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@
<srv:service id="ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForCommandWithPrivateConstructor">
<srv:tag name="prooph_service_bus.main_command_bus.route_target" message_detection="true" />
</srv:service>
<srv:service id="ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForPopoCommand" public="true">
<srv:tag name="prooph_service_bus.main_command_bus.route_target" message_detection="true" />
</srv:service>
</srv:services>
</srv:container>
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ services:
ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForCommandWithPrivateConstructor:
tags:
- { name: 'prooph_service_bus.main_command_bus.route_target', message_detection: true }

ProophTest\Bundle\ServiceBus\DependencyInjection\Fixture\Model\CommandHandlerForPopoCommand:
public: true
tags:
- { name: 'prooph_service_bus.main_command_bus.route_target', message_detection: true }