PHP code example of sbooker / domain-events-persistence
1. Go to this page and download the library: Download sbooker/domain-events-persistence library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
sbooker / domain-events-persistence example snippets
// src/UseCase/CreateProduct/Handler.php
final class Handler
{
private TransactionManager $transactionManager;
// ...
public function handle(Command $command): void
{
$this->transactionManager->transactional(function () use ($command): void {
$product = new Product(/* ... */); // Внутри создается событие
$this->transactionManager->persist($product);
// Никаких вызовов dispatchEvents()!
// Процессор сделает это автоматически перед коммитом.
});
}
}
// bootstrap.php или ваш DI-контейнер
// --- Предполагается, что у вас уже есть эти сервисы ---
/** @var Sbooker\TransactionManager\TransactionHandler $transactionHandler */
/** @var Symfony\Component\Serializer\SerializerInterface $serializer */
/** @var App\Infrastructure\Security\MyActorStorage $actorStorage */
/** @var Psr\Log\LoggerInterface $logger */
/** @var App\Infrastructure\Persistence\DoctrineConsumeStorage $consumeStorage */
// 1. Выбираем стратегию именования событий
$eventNameGiver = new Sbooker\DomainEvents\Persistence\ClassNameNameGiver();
// 2. Создаем Publisher, который будет сохранять события в БД
$persistentPublisher = new Sbooker\DomainEvents\Persistence\PersistentPublisher($eventNameGiver, $serializer);
// 3. Создаем декоратор, который добавляет Actor'а к событиям (опционально)
$actorAwarePublisher = new Sbooker\DomainEvents\ActorAwarePublisher($persistentPublisher, $actorStorage);
// 4. Создаем процессор, автоматизирующий сохранение событий
$preCommitProcessor = new Sbooker\DomainEvents\Persistence\DomainEventPreCommitProcessor($actorAwarePublisher);
// 5. Создаем TransactionManager и регистрируем в нем наш процессор.
// TransactionManager автоматически вызовет setTransactionManager() на процессоре и паблишере.
$transactionManager = new Sbooker\TransactionManager\TransactionManager(
$transactionHandler,
$preCommitProcessor
);
// 6. Создаем фабрику для консьюмеров
$consumerFactory = new Sbooker\DomainEvents\Persistence\ConsumerFactory(
$consumeStorage,
$transactionManager,
$eventNameGiver,
$serializer, // Serializer здесь выступает как Denormalizer
$logger
);
// Теперь все готово для использования!
$handler = new Handler($transactionManager, /* ... */);
// src/Email/Infrastructure/ProcessProductEventsCommand.php
use Sbooker\DomainEvents\Persistence\ConsumerFactory;
use App\Subscribers\EmailNotifier; // Ваш подписчик на события
final class ProcessProductEventsCommand extends Command
{
private ConsumerFactory $consumerFactory;
private EmailNotifier $subscriber; // Ваш сервис-обработчик
// ... constructor ...
protected function execute(InputInterface $input, OutputInterface $output): int
{
// Создаем консьюмер для конкретного подписчика.
// Имя 'email_notifier' будет использоваться для создания Pointer'а.
$consumer = $this->consumerFactory->createBySubscriber(
'email_notifier',
$this->subscriber
);
$output->writeln('Starting event consumer...');
while (true) {
// consume() атомарно находит событие, обрабатывает его и сохраняет новую позицию указателя.
$processed = $consumer->consume();
if (!$processed) {
// Если событий нет, ждем и повторяем
sleep(5);
}
}
}
}
// src/Infrastructure/Persistence/SequencePositionGenerator.php
use Sbooker\DomainEvents\Persistence\PositionGenerator;
use Sbooker\PersistentSequences\SequenceGenerator;
use Sbooker\PersistentSequences\Algorithm;
final class SequencePositionGenerator implements PositionGenerator
{
private const SEQUENCE_NAME = 'domain_events';
private SequenceGenerator $sequenceGenerator;
private Algorithm $algorithm;
public function __construct(SequenceGenerator $sequenceGenerator, Algorithm $algorithm)
{
$this->sequenceGenerator = $sequenceGenerator;
}
public function next(): int
{
// Получаем следующее значение из именованной последовательности
return $this->sequenceGenerator->next(self::SEQUENCE_NAME, $this->algorithm);
}
}
// bootstrap.php или ваш DI-контейнер
/** @var Sbooker\TransactionManager\TransactionHandler $transactionHandler */
/** @var Symfony\Component\Serializer\SerializerInterface $serializer */
/** @var SequencePositionGenerator $positionGenerator */ // <-- Ваш генератор
// 1. Создаем Publisher, передавая в него PositionGenerator
$persistentPublisher = new Sbooker\DomainEvents\Persistence\PersistentPublisher(
$eventNameGiver,
$serializer,
$positionGenerator // <-- Вот он!
);
// ... остальная сборка ...
$transactionManager = new Sbooker\TransactionManager\TransactionManager(
$transactionHandler,
$preCommitProcessor
);
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.