Created
January 22, 2016 20:44
-
-
Save guiwoda/677a2d1bfb92abee89ad to your computer and use it in GitHub Desktop.
Event store and Laravel
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
<?php | |
namespace App\Providers; | |
use Doctrine\DBAL\Connection; | |
use Illuminate\Contracts\Container\Container; | |
use Illuminate\Support\ServiceProvider; | |
use Prooph\Common\Event\ActionEvent; | |
use Prooph\Common\Event\ActionEventEmitter; | |
use Prooph\Common\Event\ActionEventListenerAggregate; | |
use Prooph\Common\Event\DetachAggregateHandlers; | |
use Prooph\Common\Event\ProophActionEventEmitter; | |
use Prooph\Common\Messaging\FQCNMessageFactory; | |
use Prooph\Common\Messaging\MessageConverter; | |
use Prooph\Common\Messaging\MessageFactory; | |
use Prooph\Common\Messaging\NoOpMessageConverter; | |
use Prooph\EventSourcing\EventStoreIntegration\AggregateTranslator as ProophAggregateTranslator; | |
use Prooph\EventStore\Adapter\Adapter as EventStoreAdapter; | |
use Prooph\EventStore\Adapter\Doctrine\DoctrineEventStoreAdapter; | |
use Prooph\EventStore\Adapter\PayloadSerializer; | |
use Prooph\EventStore\Adapter\PayloadSerializer\JsonPayloadSerializer; | |
use Prooph\EventStore\Aggregate\AggregateTranslator; | |
use Prooph\EventStore\EventStore; | |
use Prooph\EventStore\Plugin\Plugin; | |
use Prooph\EventStore\Snapshot\Adapter\Adapter as SnapshotAdapter; | |
use Prooph\EventStore\Snapshot\Adapter\Doctrine\DoctrineSnapshotAdapter; | |
use Prooph\EventStore\Snapshot\SnapshotStore; | |
use Prooph\EventStoreBusBridge\EventPublisher; | |
use Prooph\EventStoreBusBridge\TransactionManager; | |
use Prooph\ServiceBus\CommandBus; | |
use Prooph\ServiceBus\MessageBus; | |
use Prooph\ServiceBus\Plugin\Router\CommandRouter; | |
use Prooph\Snapshotter\SnapshotPlugin; | |
use Prooph\Snapshotter\Snapshotter; | |
use Prooph\Snapshotter\TakeSnapshot; | |
class EventStoreServiceProvider extends ServiceProvider | |
{ | |
/** | |
* Register the service provider. | |
* | |
* @return void | |
*/ | |
public function register() | |
{ | |
// All of these bindings may be read from config instead | |
$this->app->bind(SnapshotAdapter::class, function(){ | |
return new DoctrineSnapshotAdapter( | |
$this->app->make(Connection::class), | |
[ | |
SomeAggregate::class => 'snapshots' | |
] | |
); | |
}); | |
$this->app->bind(AggregateTranslator::class, ProophAggregateTranslator::class); | |
$this->app->bind(MessageFactory::class, FQCNMessageFactory::class); | |
$this->app->bind(MessageConverter::class, NoOpMessageConverter::class); | |
$this->app->bind(PayloadSerializer::class, JsonPayloadSerializer::class); | |
$this->app->bind(ActionEventEmitter::class, ProophActionEventEmitter::class); | |
$this->app->bind(Connection::class, function(){ | |
return $this->app['db']->getDoctrineConnection(); | |
}); | |
$this->app->bind(DoctrineEventStoreAdapter::class, function(){ | |
return new DoctrineEventStoreAdapter( | |
$this->app->make(Connection::class), | |
$this->app->make(MessageFactory::class), | |
$this->app->make(MessageConverter::class), | |
$this->app->make(PayloadSerializer::class), | |
[] | |
); | |
}); | |
$this->app->bind(SnapshotPlugin::class, function(){ | |
return new SnapshotPlugin( | |
$this->app->make(CommandBus::class), | |
10 // Read snapshot frequency from config, I'm being super lazy here... | |
); | |
}); | |
$this->app->bind(Snapshotter::class, function(){ | |
$snapshotter = new Snapshotter( | |
$this->app->make(SnapshotStore::class), | |
[ | |
SomeAggregate::class => $this->app->make(SomeAggregateRepository::class), | |
] | |
); | |
return $snapshotter; | |
}); | |
$this->app->singleton(EventStoreAdapter::class, DoctrineEventStoreAdapter::class); | |
$this->app->singleton(EventStore::class); | |
$this->app->singleton(CommandBus::class, function($app){ | |
$bus = new CommandBus(); | |
$bus->utilize(new CommandRouter([ | |
TakeSnapshot::class => Snapshotter::class, | |
])); | |
// Using Laravel's container here | |
$bus->utilize(new class($app) implements ActionEventListenerAggregate { | |
use DetachAggregateHandlers; | |
private $app; | |
/** | |
* constructor. | |
* | |
* @param $app | |
*/ | |
public function __construct(Container $app) | |
{ | |
$this->app = $app; | |
} | |
public function attach(ActionEventEmitter $dispatcher) | |
{ | |
$this->trackHandler($dispatcher->attachListener(MessageBus::EVENT_LOCATE_HANDLER, [$this, 'onLocateMessageHandler'])); | |
} | |
public function onLocateMessageHandler(ActionEvent $actionEvent) | |
{ | |
$messageHandlerAlias = $actionEvent->getParam(MessageBus::EVENT_PARAM_MESSAGE_HANDLER); | |
if (is_string($messageHandlerAlias)) | |
{ | |
// vvv HERE vvv | |
$actionEvent->setParam(MessageBus::EVENT_PARAM_MESSAGE_HANDLER, $this->app->make($messageHandlerAlias)); | |
} | |
} | |
}); | |
return $bus; | |
}); | |
// EventStore plugins could be read on resolving, of course from Config as well. | |
$this->app->resolving(EventStore::class, function(EventStore $eventStore){ | |
foreach ([ | |
EventPublisher::class, | |
TransactionManager::class, | |
SnapshotPlugin::class, | |
] as $pluginName) | |
{ | |
/** @var Plugin $plugin */ | |
$plugin = $this->app->make($pluginName); | |
$plugin->setUp($eventStore); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment