Stefan Bauer
Developer, Creator of @pingpingapp and UI/UX Enthusiast.
Blog Building PingPing Newsletter About

Using separated Commands and CommandHandlers

Published on October 24, 2017

For me personally, i don’t like the Jobs much. For me it is more logical if the commands and the handlers are separate. I also don’t like injecting the dependencies in the handle() method of the selfhandling jobs. I like the common command bus design where you have a command and a handler that handles that command.

Here i would like to show you a very easy way, how you can continue working with dedicated commands and command handlers as you did in some versions before with the regular command bus. Here we go:

Create a command

To keep it very simple, i will just create some demo code to show you the basics.

<?php

declare(strict_types=1);

namespace App\Domain\User\Command;

final class RegisterUserCommand
{
    public $username;

    public function __construct(string $username)
    {
        $this->username = $username;
    }
}

Create the corresponding command handler

After you created your command, it is time to create the command handler that handles that command.

<?php

declare(strict_types=1);

namespace App\Domain\User\Command;

final class RegisterUserCommandHandler
{
    public function handle(RegisterUserCommand $command)
    {
        // create user, dispatch event, or whatever necessary
        return 'user created with username '.$command->username;
    }
}

Time to connect them

Now that we have the command it self and the handler that should handle the command, we have to tell the dispatcher which handler is responsible for which command. Easy! There are several ways to do that. The easiest way is that you use a ServiceProvider for it or use the already existing AppServiceProvider.

Either you fetch the current Dispatcher out of the IoC directly or you just inject it into the boot() method. I will show you both methods. After you resolved the Dispatcher, you use the map() method to map the command to the command handler.

Resolving directly out of the IoC

<?php

namespace App\Providers;

use App\Domain\User\Command\RegisterUserCommand;
use App\Domain\User\Command\RegisterUserCommandHandler;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $dispatcher = $this->app->make(\Illuminate\Contracts\Bus\Dispatcher::class);
        $dispatcher->map([
            RegisterUserCommand::class => RegisterUserCommandHandler::class,
        ]);
    }

    // register() method...

}

or using DI

<?php

namespace App\Providers;

use App\Domain\User\Command\RegisterUserCommand;
use App\Domain\User\Command\RegisterUserCommandHandler;
use Illuminate\Bus\Dispatcher;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(Dispatcher $dispatcher)
    {
        $dispatcher->map([
            RegisterUserCommand::class => RegisterUserCommandHandler::class,
        ]);
    }

    // register() method....

}

We should try it

Let’s give it a shot and try it. We use the route file directly to test that. Like so:

Route::get('dispatch', function(\Illuminate\Bus\Dispatcher $dispatcher) {
    return \Bus::dispatch(new \App\Domain\User\Command\RegisterUserCommand('my-username'));
});

If you go now to the browser you should see something like “user created with username my-username“. Yiha!

If you have enyoyed my posts or you like what i am talking/twittering about, you should signup. I will show you everything i know about development and UI/UX.

Imprint Privacy Policy
Proudly hosted with Vultr