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: 2 additions & 2 deletions docs/infrastructure/doctrine-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ An overview of available infrastructural code when using Doctrine's [Collections
## Domain Collection

A Doctrine tailored [domain collection](../ddd/collections.md) is provided by `MsgPhp\Domain\Infra\Doctrine\DomainCollection`.
It leverages type `Doctrine\Common\Collections\Collection` as underlying data type.
It decorates any `Doctrine\Common\Collections\Collection` type.

- `__construct(Collection $collection)`
- `$collection`: The underlying collection
- `$collection`: The decorated collection

### Basic example

Expand Down
35 changes: 35 additions & 0 deletions docs/infrastructure/simple-bus.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# SimpleBus

An overview of available infrastructural code when using [SimpleBus].

- Requires [simple-bus/message-bus]

## Domain Message Bus

A SimpleBus tailored [domain message bus](../message-driven/message-bus.md) is provided by `MsgPhp\Domain\Infra\SimpleBus\DomainMessageBus`.
It decorates any `SimpleBus\Message\Bus\MessageBus` type.

- `__construct(MessageBus $bus)`
- `$bus`: The decorated bus

### Basic example

```php
<?php

use MsgPhp\Domain\Infra\SimpleBus\DomainMessageBus;
use SimpleBus\Message\Bus\MessageBus

// --- SETUP ---

/** @var MessageBus $bus */
$bus = ...;
$domainBus = new DomainMessageBus($bus);

// --- USAGE ---

$result = $domainBus->dispatch(new SomeMessage());
```

[SimpleBus]: http://docs.simplebus.io
[simple-bus/message-bus]: https://packagist.org/packages/simple-bus/message-bus
35 changes: 35 additions & 0 deletions docs/infrastructure/symfony-messenger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Symfony Messenger

An overview of available infrastructural code when using [Symfony Messenger][messenger-project].

- Requires [symfony/messenger]

## Domain Message Bus

A Symfony Messenger tailored [domain message bus](../message-driven/message-bus.md) is provided by `MsgPhp\Domain\Infra\Messenger\DomainMessageBus`.
It decorates any `Symfony\Component\Messenger\MessageBusInterface` type.

- `__construct(MessageBusInterface $bus)`
- `$bus`: The decorated bus

### Basic example

```php
<?php

use MsgPhp\Domain\Infra\Messenger\DomainMessageBus;
use Symfony\Component\Messenger\MessageBusInterface;

// --- SETUP ---

/** @var MessageBusInterface $bus */
$bus = ...;
$domainBus = new DomainMessageBus($bus);

// --- USAGE ---

$result = $domainBus->dispatch(new SomeMessage());
```

[messenger-project]: https://symfony.com/doc/current/components/messenger.html
[symfony/messenger]: https://packagist.org/packages/symfony/messenger
13 changes: 11 additions & 2 deletions docs/message-driven/message-bus.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,14 @@ Dispatches the given message object. The bus can return a value coming from hand

## Implementations

- `MsgPhp\Domain\Infra\SimpleBus\DomainMessageBus`
- Requires [`simple-bus/message-bus`](https://packagist.org/packages/simple-bus/message-bus)
### `MsgPhp\Domain\Infra\Messenger\DomainMessageBus`

A Symfony Messenger tailored domain message bus.

- [Read more](../infrastructure/symfony-messenger.md#domain-message-bus)

### `MsgPhp\Domain\Infra\SimpleBus\DomainMessageBus`

A SimpleBus tailored domain message bus.

- [Read more](../infrastructure/simple-bus.md#domain-message-bus)
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ pages:
- Doctrine ORM: infrastructure/doctrine-orm.md
- Elasticsearch: infrastructure/elasticsearch.md
- PSR Container: infrastructure/psr-container.md
- SimpleBus: infrastructure/simple-bus.md
- Symfony Console: infrastructure/symfony-console.md
- Symfony Messenger: infrastructure/symfony-messenger.md
- UUID: infrastructure/uuid.md
- Cookbook:
- Bundle Installation: cookbook/bundle-installation.md
Expand Down
36 changes: 36 additions & 0 deletions src/Domain/Infra/Console/MessageReceiver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace MsgPhp\Domain\Infra\Console;

use MsgPhp\Domain\Message\MessageReceivingInterface;
use Symfony\Component\Console\Event\ConsoleCommandEvent;

/**
* @author Roland Franssen <franssen.roland@gmail.com>
*/
final class MessageReceiver
{
/** @var MessageReceivingInterface|null */
private $receiver;

public function receive($message): void
{
if (null === $this->receiver) {
return;
}

$this->receiver->onMessageReceived($message);
}

public function onCommand(ConsoleCommandEvent $event): void
{
$this->receiver = ($command = $event->getCommand()) instanceof MessageReceivingInterface ? $command : null;
}

public function onTerminate(): void
{
$this->receiver = null;
}
}
113 changes: 69 additions & 44 deletions src/Domain/Infra/DependencyInjection/BundleHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Doctrine\ORM\Events as DoctrineOrmEvents;
use Doctrine\ORM\Version as DoctrineOrmVersion;
use MsgPhp\Domain\Infra\{Console as ConsoleInfra, Doctrine as DoctrineInfra};
use MsgPhp\Domain\Infra\{Console as ConsoleInfra, Doctrine as DoctrineInfra, SimpleBus as SimpleBusInfra};
use SimpleBus\SymfonyBridge\SimpleBusCommandBusBundle;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Container;
Expand All @@ -28,51 +29,11 @@ public static function initDomain(ContainerBuilder $container): void
return;
}

if (class_exists(ConsoleEvents::class)) {
$container->register(ConsoleInfra\Context\ClassContextFactory::class)
->setPublic(false)
->setAbstract(true)
->setAutowired(true)
->setArgument('$method', '__construct')
->setArgument('$classMapping', '%msgphp.domain.class_mapping%');

$container->register(ConsoleInfra\Context\ClassContextElementFactory::class)
->setPublic(false);

$container->setAlias(ConsoleInfra\Context\ClassContextElementFactoryInterface::class, new Alias(ConsoleInfra\Context\ClassContextElementFactory::class, false));
}

if (class_exists(DoctrineOrmVersion::class)) {
$container->addCompilerPass(new Compiler\DoctrineObjectFieldMappingPass());

$container->register(DoctrineInfra\Event\ObjectFieldMappingListener::class)
->setPublic(false)
->setArgument('$mapping', [])
->addTag('doctrine.event_listener', ['event' => DoctrineOrmEvents::loadClassMetadata])
->addTag('msgphp.domain.process_class_mapping', ['argument' => '$mapping']);

if (ContainerHelper::hasBundle($container, DoctrineBundle::class)) {
@mkdir($mappingDir = $container->getParameterBag()->resolveValue('%kernel.cache_dir%/msgphp/doctrine-mapping'), 0777, true);

$container->prependExtensionConfig('doctrine', ['orm' => [
'hydrators' => [
DoctrineInfra\Hydration\ScalarHydrator::NAME => DoctrineInfra\Hydration\ScalarHydrator::class,
DoctrineInfra\Hydration\SingleScalarHydrator::NAME => DoctrineInfra\Hydration\SingleScalarHydrator::class,
],
'mappings' => [
'msgphp' => [
'dir' => $mappingDir,
'type' => 'xml',
'prefix' => 'MsgPhp',
'is_bundle' => false,
],
],
]]);
}
}

$container->addCompilerPass(new Compiler\ResolveDomainPass());

self::initConsole($container);
self::initDoctrineOrm($container);

$initialized = true;
}

Expand All @@ -92,6 +53,70 @@ public static function initDoctrineTypes(Container $container): void
$initialized = true;
}

private static function initConsole(ContainerBuilder $container): void
{
if (!class_exists(ConsoleEvents::class)) {
return;
}

$container->register(ConsoleInfra\Context\ClassContextFactory::class)
->setPublic(false)
->setAbstract(true)
->setAutowired(true)
->setArgument('$method', '__construct')
->setArgument('$classMapping', '%msgphp.domain.class_mapping%');

$container->register(ConsoleInfra\Context\ClassContextElementFactory::class)
->setPublic(false);

$container->setAlias(ConsoleInfra\Context\ClassContextElementFactoryInterface::class, new Alias(ConsoleInfra\Context\ClassContextElementFactory::class, false));

$container->register(ConsoleInfra\MessageReceiver::class)
->setPublic(false)
->addTag('kernel.event_listener', ['event' => ConsoleEvents::COMMAND, 'method' => 'onCommand'])
->addTag('kernel.event_listener', ['event' => ConsoleEvents::TERMINATE, 'method' => 'onTerminate']);

if (ContainerHelper::hasBundle($container, SimpleBusCommandBusBundle::class)) {
$container->register(SimpleBusInfra\Middleware\ConsoleMessageReceiverMiddleware::class)
->setPublic(false)
->setAutowired(true)
->addTag('command_bus_middleware');
}
}

private static function initDoctrineOrm(ContainerBuilder $container): void
{
if (!class_exists(DoctrineOrmVersion::class)) {
return;
}

$container->addCompilerPass(new Compiler\DoctrineObjectFieldMappingPass());

$container->register(DoctrineInfra\Event\ObjectFieldMappingListener::class)
->setPublic(false)
->setArgument('$mapping', [])
->addTag('doctrine.event_listener', ['event' => DoctrineOrmEvents::loadClassMetadata]);

if (ContainerHelper::hasBundle($container, DoctrineBundle::class)) {
@mkdir($mappingDir = $container->getParameterBag()->resolveValue('%kernel.cache_dir%/msgphp/doctrine-mapping'), 0777, true);

$container->prependExtensionConfig('doctrine', ['orm' => [
'hydrators' => [
DoctrineInfra\Hydration\ScalarHydrator::NAME => DoctrineInfra\Hydration\ScalarHydrator::class,
DoctrineInfra\Hydration\SingleScalarHydrator::NAME => DoctrineInfra\Hydration\SingleScalarHydrator::class,
],
'mappings' => [
'msgphp' => [
'dir' => $mappingDir,
'type' => 'xml',
'prefix' => 'MsgPhp',
'is_bundle' => false,
],
],
]]);
}
}

private static function &getInitialized(Container $container, string $key)
{
if (!isset(self::$initialized[$hash = spl_object_hash($container)."\0".$key])) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@

use Doctrine\ORM\EntityManagerInterface as DoctrineEntityManager;
use MsgPhp\Domain\{DomainIdentityHelper, DomainIdentityMappingInterface, Factory, Message};
use MsgPhp\Domain\Infra\{Doctrine as DoctrineInfra, InMemory as InMemoryInfra, SimpleBus as SimpleBusInfra};
use MsgPhp\Domain\Infra\{Console as ConsoleInfra, Doctrine as DoctrineInfra, InMemory as InMemoryInfra, Messenger as MessengerInfra, SimpleBus as SimpleBusInfra};
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Component\Messenger\MessageBusInterface;

/**
* @author Roland Franssen <franssen.roland@gmail.com>
Expand Down Expand Up @@ -143,13 +145,28 @@ private function registerEntityFactory(ContainerBuilder $container, array $idCla

private function registerMessageBus(ContainerBuilder $container): void
{
if (!$container->has('simple_bus.command_bus')) {
return;
$aliasId = null;

if ($container->has('simple_bus.command_bus')) {
self::register($container, $aliasId = SimpleBusInfra\DomainMessageBus::class)
->setArgument('$bus', new Reference('simple_bus.command_bus'));
}

self::register($container, $aliasId = SimpleBusInfra\DomainMessageBus::class)
->setArgument('$bus', new Reference('simple_bus.command_bus'));
if ($container->has(MessageBusInterface::class)) {
self::register($container, $aliasId = MessengerInfra\DomainMessageBus::class)
->setAutowired(true);

if (class_exists(ConsoleEvents::class)) {
foreach ($container->findTaggedServiceIds('messenger.bus') as $id => $attr) {
self::register($container, MessengerInfra\ConsoleMessageReceiverBus::class, MessengerInfra\ConsoleMessageReceiverBus::class.'.'.$id)
->setDecoratedService($id)
->setArgument('$bus', MessengerInfra\ConsoleMessageReceiverBus::class.'.'.$id.'.inner');
}
}
}

self::alias($container, Message\DomainMessageBusInterface::class, $aliasId);
if (null !== $aliasId) {
self::alias($container, Message\DomainMessageBusInterface::class, $aliasId);
}
}
}
Loading