Imagine a "clean architecture" in which you have two use cases. One of them is CreateCustomerHandler, and the other SignUpCustomerByGoogleAuthHandler. So, the SignUpCustomerByGoogleAuthHandler has to reuse the CreateCustomerHandler to eventually create a Customer.
Is it legit to inject CreateCustomerHandler to SignUpCustomerByGoogleAuthHandler as dependency? Are there any pitfalls?
I read somewhere that it's not recommended to reuse your use cases, but what to do in that simple case? Extract the whole CreateCustomerHandler as Application Service and inject it both to the CreateCustomerHandler and SignUpCustomerByGoogleAuthHandler use cases?
CreateCustomerHandler
<?php declare(strict_types=1); namespace App\Identity\Application\Customer\UseCase\CreateCustomer; use App\Identity\Application\Customer\CustomerEntityManager; use App\Identity\Application\Security\PasswordEncoder; use App\Identity\Domain\Customer\Customer; use App\Identity\Domain\Customer\Name; use App\Identity\Domain\Customer\Username; use App\Identity\Domain\User\Email; use App\Identity\Domain\User\Password; final class CreateCustomerHandler { private CustomerEntityManager $customerEntityManager; private PasswordEncoder $passwordEncoder; public function __construct(CustomerEntityManager $customerEntityManagerByActiveTenant, PasswordEncoder $passwordEncoder) { $this->customerEntityManager = $customerEntityManagerByActiveTenant; $this->passwordEncoder = $passwordEncoder; } public function handle(CreateCustomerCommand $command): Customer { $customerId = $this->customerEntityManager->nextId(); $email = new Email($command->email()); $username = new Username($command->username()); $name = new Name($command->firstname(), $command->lastname()); $password = $this->passwordEncoder->encodePassword($command->password()); $password = new Password($password); $customer = new Customer( $customerId, $email, $password, $username, $name, ); $this->customerEntityManager->create($customer); return $customer; } } SignInCustomerByGoogleAuthHandler
<?php declare(strict_types=1); namespace App\Identity\Application\Customer\UseCase\SignInCustomerByGoogleAuth; use App\Identity\Application\Customer\CustomerEntityManager; use App\Identity\Application\Customer\Query\CustomerByGoogleAuthQuery; use App\Identity\Application\Customer\UseCase\CreateCustomer\CreateCustomerCommand; use App\Identity\Application\Customer\UseCase\CreateCustomer\CreateCustomerHandler; use App\Identity\Application\Security\Security; use App\Identity\Application\User\UseCase\LinkGoogleAuth\GoogleAuth; use App\Identity\Domain\Customer\Customer; final class SignInCustomerByGoogleAuthHandler { private CustomerByGoogleAuthQuery $customerByGoogleAuthQuery; private GoogleAuth $googleAuth; private CreateCustomerHandler $createCustomerHandler; private CustomerEntityManager $customerEntityManager; private Security $security; public function __construct(CustomerByGoogleAuthQuery $customerByGoogleAuthQuery, CreateCustomerHandler $createCustomerHandler, CustomerEntityManager $customerEntityManager, Security $security, GoogleAuth $googleAuth) { $this->customerByGoogleAuthQuery = $customerByGoogleAuthQuery; $this->googleAuth = $googleAuth; $this->createCustomerHandler = $createCustomerHandler; $this->customerEntityManager = $customerEntityManager; $this->security = $security; } public function handle(SignInCustomerByGoogleAuthCommand $command): Customer { $code = $command->code(); $oauthUser = $this->googleAuth->userByOneTimeCode($code); $customer = $this->customerByGoogleAuthQuery->queryByGoogleUser($oauthUser); $username = $this->customerEntityManager->nextId()->value(); $password = $this->security->randomPassword(); if (!$customer) { $command = new CreateCustomerCommand( $oauthUser->email(), $username, $password->hash(), $oauthUser->firstname(), $oauthUser->lastname(), ); $customer = $this->createCustomerHandler->handle($command); } // TODO $customer->allowAuthVendor(); return $customer; } }