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

Tactician Container Laravel Package

league/tactician-container

PSR-11 container plugin for League Tactician that lazily loads command handlers from your DI container. Install via Composer and integrate with Tactician to resolve handlers on demand for cleaner wiring and faster bootstrap.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Event-Driven & CQRS Alignment: The package integrates seamlessly with Tactician, a PHP command bus library, enabling lazy-loaded command handlers via PSR-11 containers (e.g., Laravel’s Illuminate/Container). This is ideal for CQRS/Event Sourcing architectures where commands are processed asynchronously or in a decoupled manner.
  • Dependency Injection (DI) Compatibility: Leverages Laravel’s built-in PSR-11 container (via Illuminate/Container), eliminating the need for additional infrastructure. Aligns with Laravel’s service container philosophy.
  • Modularity: Enables handler resolution on-demand, reducing memory overhead for rarely used commands (e.g., background jobs, admin actions).
  • Extensibility: Works with any PSR-11 container, making it future-proof if Laravel evolves its DI system (e.g., moving to PSR-11 natively).

Integration Feasibility

  • Low Friction: Minimal setup—just composer require league/tactician-container and bind handlers to the container (Laravel’s bind() or singleton() methods).
  • Tactician Ecosystem: Integrates with Tactician’s middleware stack (e.g., logging, validation), which can be leveraged for cross-cutting concerns (e.g., auth, retries).
  • Laravel-Specific Synergies:
    • Works with Laravel’s job queue (e.g., Bus::dispatch() → Tactician command bus).
    • Compatible with Laravel’s event system (e.g., dispatching commands from listeners).
    • Can integrate with Laravel Nova for admin-driven command execution.

Technical Risk

  • Container Binding Complexity:
    • Risk: Improper handler binding (e.g., circular dependencies, incorrect type hints) may cause runtime errors.
    • Mitigation: Use Laravel’s app()->bind() with explicit interfaces and constructor injection.
  • Tactician Version Lock:
    • Risk: Package requires Tactician ^1.0, which may have breaking changes if Tactician evolves.
    • Mitigation: Monitor Tactician’s release notes and test upgrades incrementally.
  • Performance Overhead:
    • Risk: Lazy loading may introduce reflection overhead for handlers.
    • Mitigation: Benchmark critical paths; cache resolved handlers if needed (e.g., via singleton()).
  • PSR-11 Compliance:
    • Risk: Laravel’s container is PSR-11-compliant but not PSR-20 (which adds get() with type hints).
    • Mitigation: Ensure handlers are bound with explicit types to avoid ambiguity.

Key Questions

  1. Use Case Clarity:
    • Are we using this for synchronous commands (e.g., API endpoints) or asynchronous workflows (e.g., queues)?
    • Does the team need Tactician’s middleware (e.g., retry logic, validation) beyond basic command handling?
  2. Container Strategy:
    • Should handlers be singletons (for stateless operations) or resolved fresh (for stateful workflows)?
    • How will we handle container binding conflicts (e.g., duplicate bindings)?
  3. Testing & Observability:
    • How will we mock/verify command execution in tests (e.g., using Tactician’s CommandTestCase)?
    • Are there logging/monitoring requirements for command processing?
  4. Migration Path:
    • Are we replacing an existing command bus (e.g., Laravel’s Bus facade) or augmenting it?
    • How will this interact with Laravel’s job middleware (e.g., HandleJobsMiddleware)?

Integration Approach

Stack Fit

  • Laravel Core Integration:
    • Replace or extend Laravel’s Bus facade with Tactician’s CommandBus, configured via app/Providers/AppServiceProvider.
    • Example:
      $this->app->bind(\League\Tactician\CommandBus::class, function ($app) {
          $container = new \League\Tactician\Container\ContainerPlugin();
          $bus = new \League\Tactician\CommandBus(
              $container,
              new \League\Tactician\Middleware\MiddlewareStack()
          );
          return $bus;
      });
      
  • Handler Binding:
    • Bind handlers to the container using Laravel’s syntax:
      $this->app->bind(\App\Commands\ProcessOrder::class, function ($app) {
          return new ProcessOrderHandler($app->make(OrderRepository::class));
      });
      
  • Middleware Integration:
    • Add Tactician middleware (e.g., logging, validation) to the MiddlewareStack:
      $middlewareStack = new \League\Tactician\Middleware\MiddlewareStack();
      $middlewareStack->add(new \League\Tactician\Middleware\LoggingMiddleware());
      

Migration Path

  1. Phase 1: Pilot Integration
    • Start with non-critical commands (e.g., admin actions, background jobs).
    • Replace direct handler calls with Bus::dispatch().
    • Example:
      // Before
      $handler = new ProcessOrderHandler($orderRepo);
      $handler->handle(new ProcessOrder($orderId));
      
      // After
      Bus::dispatch(new ProcessOrder($orderId));
      
  2. Phase 2: Middleware Adoption
    • Gradually add Tactician middleware (e.g., validation, retries) to replace custom logic.
  3. Phase 3: Full Replacement
    • Migrate all command-related logic to Tactician, decommission legacy bus implementations.

Compatibility

  • Laravel Versions:
    • Tested with Laravel 8+ (PHP 7.4+). Compatible with Lumen (if using PSR-11 container).
    • May require adjustments for Laravel 9+ if Tactician drops PHP 7.4 support.
  • Existing Code:
    • Handlers must implement League\Tactician\CommandHandlerInterface.
    • Commands must be immutable DTOs (recommended by Tactician).
  • Third-Party Packages:
    • Conflicts possible with other PSR-11 container plugins (e.g., league/container). Use namespace isolation if needed.

Sequencing

  1. Setup:
    • Install package and Tactician.
    • Configure container bindings in AppServiceProvider.
  2. Development:
    • Write handlers with explicit dependencies (use app()->make() or constructor injection).
    • Test with Bus::dispatch() in unit/integration tests.
  3. Deployment:
    • Monitor handler resolution performance (e.g., via Laravel Debugbar).
    • Roll out in stages (e.g., start with read commands, then write commands).
  4. Optimization:
    • Cache frequently used handlers (e.g., via singleton()).
    • Add circuit breakers for critical commands (e.g., using Tactician middleware).

Operational Impact

Maintenance

  • Pros:
    • Reduced Boilerplate: No need to manually instantiate handlers or manage middleware.
    • Centralized Configuration: All command logic lives in the container, making it easier to update.
    • Community Support: Tactician is a mature library with active maintenance (last release: 2023).
  • Cons:
    • Debugging Complexity: Container resolution errors (e.g., missing bindings) may be harder to trace than direct instantiation.
    • Dependency Sprawl: Adding Tactician introduces new abstractions (e.g., middleware stack) that require documentation.

Support

  • Troubleshooting:
    • Use Laravel’s app()->bound() to verify handler bindings.
    • Tactician provides CommandBusException for runtime errors (e.g., unhandled commands).
  • Tooling:
    • Integrate with Laravel Horizon for queue-based command monitoring.
    • Use Tactician’s CommandTestCase for automated testing.
  • Team Onboarding:
    • Document handler binding conventions (e.g., naming, interfaces).
    • Provide examples for common patterns (e.g., async commands, middleware).

Scaling

  • Performance:
    • Lazy Loading: Reduces memory usage for rarely used commands.
    • Middleware Overhead: Each middleware adds ~1–5ms per command. Benchmark for high-throughput systems.
  • Horizontal Scaling:
    • Works seamlessly with Laravel Forge/Envoyer and queue workers.
    • For serverless (e.g., Bref), ensure handlers are stateless and use singletons for shared resources.
  • Database Load:
    • Tactician’s transaction middleware can help manage DB transactions per command.

Failure Modes

| Failure Scenario | Impact | Mitigation | |-------------------------------------|--------------------------------

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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle