Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Toolkit Laravel Package

domain-engine/toolkit

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Run composer require domain-engine/toolkit in your Laravel project. While this is a Symfony bundle, Laravel can integrate it via Symfony Bridge or by manually adapting its components.

  2. Enable Core Functionality Register the bundle in config/app.php under providers:

    'providers' => [
        // ...
        DomainEngine\ToolkitBundle\ToolkitBundle::class,
    ],
    
  3. First Use Case: Annotate a Value Object Define a simple value object in your domain layer (e.g., app/Domain/ValueObject/Email.php):

    namespace App\Domain\ValueObject;
    
    use DomainEngine\Toolkit\Annotation\ValueObject;
    
    #[ValueObject]
    class Email
    {
        public function __construct(private string $address) {}
    
        public function getAddress(): string { return $this->address; }
    }
    
  4. Autoload Annotations Configure Symfony’s annotation autoloader in composer.json:

    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": ["vendor/domain-engine/toolkit"]
    }
    

    Run composer dump-autoload.


Implementation Patterns

Workflows

  1. Domain Events & Process Manager

    • Emit Events: Trigger domain events in your aggregate root:
      use DomainEngine\Toolkit\Annotation\DomainEvent;
      
      #[DomainEvent]
      class OrderCreated {}
      
      // In AggregateRoot:
      $this->recordThat(new OrderCreated($orderId));
      
    • Handle Events: Use the ProcessManager to orchestrate workflows:
      use DomainEngine\Toolkit\ProcessManager;
      
      $processManager = app(ProcessManager::class);
      $processManager->handle(new OrderCreated($orderId));
      
  2. Command Handling

    • Define Commands:
      use DomainEngine\Toolkit\Annotation\Command;
      
      #[Command]
      class CreateOrder {}
      
    • Register Handlers: Bind handlers in Laravel’s service container:
      $this->app->bind(
          CommandHandler::class,
          fn() => new CommandHandler(app(Dispatcher::class))
      );
      
  3. Aggregate Roots

    • Annotate Aggregates:
      use DomainEngine\Toolkit\Annotation\AggregateRoot;
      
      #[AggregateRoot]
      class Order {}
      
    • Leverage Domain Logic: Use DomainEvent annotations to auto-publish events.

Integration Tips

  • Symfony Messenger Bridge Use Laravel’s Illuminate\Bus\Dispatcher to integrate with Symfony Messenger:

    $dispatcher = app(Dispatcher::class);
    $messenger = new Messenger($dispatcher);
    $processManager = new ProcessManager($messenger);
    
  • Laravel Service Container Bind toolkit services explicitly:

    $this->app->singleton(ProcessManager::class, fn() => new ProcessManager(app(Messenger::class)));
    
  • Event Listeners Convert Symfony Messenger listeners to Laravel events:

    // Symfony Messenger Listener
    $messenger->addListener(OrderCreated::class, fn(OrderCreated $event) => ...);
    
    // Laravel Event Listener
    event(new OrderCreated($orderId));
    

Gotchas and Tips

Pitfalls

  1. Annotation Processing

    • Issue: Annotations may not load if Symfony’s autoloader isn’t configured.
    • Fix: Ensure composer dump-autoload is run post-installation.
  2. Messenger Integration

    • Issue: Laravel’s Dispatcher and Symfony’s Messenger have different expectations.
    • Fix: Use a bridge (e.g., symfony/messenger-bridge) or wrap the Dispatcher in a Messenger adapter.
  3. Aggregate Root State

    • Issue: Toolkit assumes aggregates are immutable by default. Manual state changes may break invariants.
    • Fix: Use DomainEvent annotations for all state transitions.

Debugging

  • Enable Debug Mode Configure Symfony’s debug mode in config/packages/domain_engine_toolkit.yaml:

    framework:
        messenger:
            debug: true
    
  • Log Domain Events Add a listener to log events for debugging:

    $messenger->addListener(DomainEvent::class, fn($event) => \Log::debug($event));
    

Extension Points

  1. Custom Annotations Extend the annotation system by creating new attributes:

    #[Attribute]
    class CustomAnnotation {}
    
  2. Process Manager Plugins Override the ProcessManager to add custom workflow logic:

    class CustomProcessManager extends ProcessManager
    {
        protected function getHandlers(): array
        {
            return array_merge(parent::getHandlers(), [
                CustomEvent::class => new CustomHandler(),
            ]);
        }
    }
    
  3. Value Object Validation Add validation logic to value objects:

    #[ValueObject]
    class Email
    {
        public function __construct(string $address)
        {
            if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
                throw new \InvalidArgumentException("Invalid email");
            }
            $this->address = $address;
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
aimeos/prisma
besmartand-pro/php-quality-config
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views