Skip to content

Instantly share code, notes, and snippets.

@guiwoda
Created January 22, 2016 20:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guiwoda/677a2d1bfb92abee89ad to your computer and use it in GitHub Desktop.
Save guiwoda/677a2d1bfb92abee89ad to your computer and use it in GitHub Desktop.
Event store and Laravel
<?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