-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from young-steveo/conveyor
Initial, broken, untested CQRS implementation
- Loading branch information
Showing
22 changed files
with
386 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Arcanum\Conveyor; | ||
|
||
interface Bus | ||
{ | ||
/** | ||
* Dispatch an object to a handler. | ||
* | ||
* The object to be dispatched should be a simple DTO, and the | ||
* return value should be a simple DTO. | ||
*/ | ||
public function dispatch(object $object): object; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Arcanum\Conveyor; | ||
|
||
/** | ||
* DTO validates that an object is a simple DTO. | ||
*/ | ||
final class DTO implements Validator | ||
{ | ||
/** | ||
* Validate a DTO. | ||
*/ | ||
public function validate(object $object): void | ||
{ | ||
$image = new \ReflectionClass($object); | ||
$name = $image->getName(); | ||
|
||
if (!$image->isInstantiable()) { | ||
throw new InvalidDTO("$name is not instantiable."); | ||
} | ||
|
||
if (!$image->isFinal()) { | ||
throw new InvalidDTO("$name is not final."); | ||
} | ||
|
||
$properties = $image->getProperties(); | ||
|
||
foreach ($properties as $property) { | ||
if (!$property->isPublic()) { | ||
$propertyName = $property->getName(); | ||
throw new InvalidDTO("$name has non-public property $propertyName."); | ||
} | ||
|
||
if ($property->isStatic()) { | ||
$propertyName = $property->getName(); | ||
throw new InvalidDTO("$name has static property $propertyName."); | ||
} | ||
|
||
if (!$property->isReadOnly()) { | ||
$propertyName = $property->getName(); | ||
throw new InvalidDTO("$name has non-read-only property $propertyName."); | ||
} | ||
} | ||
|
||
$methods = $image->getMethods(); | ||
|
||
foreach ($methods as $method) { | ||
if ($method->isPublic()) { | ||
$methodName = $method->getName(); | ||
throw new InvalidDTO("$name has public method $methodName."); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Arcanum\Conveyor; | ||
|
||
/** | ||
* Empty is a DTO that has no data. | ||
*/ | ||
final class EmptyDTO | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Arcanum\Conveyor; | ||
|
||
final class InvalidDTO extends \InvalidArgumentException | ||
{ | ||
public function __construct(string $message = '', int $code = 0, \Throwable $previous = null) | ||
{ | ||
parent::__construct("Invalid DTO: $message", $code, $previous); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Arcanum\Conveyor; | ||
|
||
use Arcanum\Cabinet\Container; | ||
|
||
class StrictBus extends SwiftBus | ||
{ | ||
/** | ||
* @var Validator[] | ||
*/ | ||
protected array $validators; | ||
|
||
/** | ||
* StrictBus | ||
* | ||
* This bus validates that the object being dispatched passes the validators | ||
* and that the response from the handler passes the validators. | ||
*/ | ||
public function __construct(protected Container $container, Validator ...$validators) | ||
{ | ||
parent::__construct($container); | ||
$this->validators = $validators; | ||
} | ||
|
||
/** | ||
* Dispatch an object to a handler. | ||
*/ | ||
public function dispatch(object $object): object | ||
{ | ||
$this->validateObject($object); | ||
$response = parent::dispatch($object); | ||
$this->validateObject($response); | ||
return $response; | ||
} | ||
|
||
/** | ||
* Validate that an object is a simple DTO. | ||
* | ||
* A simple DTO is a class that is final, has only public, non-static, | ||
* read-only properties, and has no public methods. | ||
*/ | ||
protected function validateObject(object $object): void | ||
{ | ||
foreach ($this->validators as $validator) { | ||
$validator->validate($object); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Arcanum\Conveyor; | ||
|
||
use Arcanum\Cabinet\Container; | ||
|
||
class SwiftBus implements Bus | ||
{ | ||
public function __construct(protected Container $container) | ||
{ | ||
} | ||
|
||
/** | ||
* Dispatch an object to a handler. | ||
*/ | ||
public function dispatch(object $object): object | ||
{ | ||
return $this->handlerFor($object)($object) ?? new EmptyDTO(); | ||
} | ||
|
||
/** | ||
* Get the handler for an object. | ||
* | ||
* SwiftBus assumes that the handler is a callable. | ||
*/ | ||
protected function handlerFor(object $object): callable | ||
{ | ||
/** @var callable */ | ||
return $this->container->get($this->handlerNameFor($object)); | ||
} | ||
|
||
/** | ||
* Get the handler name for an object. | ||
* | ||
* This is the class name of the object with the suffix "Handler". | ||
* | ||
* @return class-string | ||
*/ | ||
protected function handlerNameFor(object $object): string | ||
{ | ||
/** @var class-string */ | ||
return get_class($object) . 'Handler'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Arcanum\Conveyor; | ||
|
||
interface Validator | ||
{ | ||
/** | ||
* Validate an object | ||
*/ | ||
public function validate(object $object): void; | ||
} |
Oops, something went wrong.