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

Strategy Injector Laravel Package

4xxi/strategy-injector

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Run:

    composer require 4xxi/strategy-injector
    

    Ensure config/packages/strategy_injector.yaml exists with the basic structure.

  2. First Use Case: Constructor Injection Define a composite class (e.g., CompositeFooStrategy) that implements App\Strategy\FooStrategyInterface. Configure the bundle to inject all implementing classes into the composite:

    strategy_injector:
        App\Strategy\FooStrategyInterface: App\Strategy\CompositeFooStrategy
    
  3. First Use Case: Method Injection Configure a method (e.g., addStrategy) to dynamically inject strategies:

    strategy_injector:
        App\Strategy\FooStrategyInterface:
            method: 'addStrategy'
            class: App\Strategy\CompositeFooStrategy
    
  4. Verify Autowiring Ensure your services.yaml includes:

    App\Strategy\CompositeFooStrategy: ~
    

    And that the composite class is properly tagged or autowired.


Implementation Patterns

Core Workflow

  1. Define Interfaces and Implementations Create a strategy interface (e.g., FooStrategyInterface) and multiple implementations (e.g., BarStrategy, BazStrategy). Implement a composite class (e.g., CompositeFooStrategy) that aggregates these strategies.

  2. Configure Constructor Injection Use the bundle to inject all implementations of an interface into the composite via its constructor:

    strategy_injector:
        App\Strategy\FooStrategyInterface: App\Strategy\CompositeFooStrategy
    

    The composite’s constructor should accept an array of strategies:

    public function __construct(array $strategies) { ... }
    
  3. Dynamic Method Injection For runtime flexibility, configure method injection:

    strategy_injector:
        App\Strategy\FooStrategyInterface:
            method: 'addStrategy'  // Method on CompositeFooStrategy
            class: App\Strategy\CompositeFooStrategy
    

    The composite class must implement addStrategy to accept new strategies:

    public function addStrategy(FooStrategyInterface $strategy) { ... }
    
  4. Integration with Symfony Services Use the composite class in controllers/services:

    use App\Strategy\CompositeFooStrategy;
    
    class MyService {
        public function __construct(private CompositeFooStrategy $composite) { ... }
    }
    

Advanced Patterns

  • Conditional Injection Extend the composite class to filter strategies based on runtime conditions (e.g., environment variables, user roles). Example:

    public function __construct(array $strategies, $environment) {
        $this->strategies = array_filter($strategies, fn($s) => $s->supports($environment));
    }
    
  • Strategy Prioritization Implement a getPriority() method in strategies and sort them in the composite:

    public function __construct(array $strategies) {
        usort($strategies, fn($a, $b) => $b->getPriority() <=> $a->getPriority());
        $this->strategies = $strategies;
    }
    
  • Lazy Loading Use method injection to add strategies on-demand (e.g., via API calls):

    $composite->addStrategy(new DynamicStrategy());
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies Ensure the composite class and its strategies do not create circular references in the container. Fix: Use autowire: false and manually define services in services.yaml.

  2. Missing Interface Implementations If no classes implement App\Strategy\FooStrategyInterface, the composite will receive an empty array. Fix: Validate configurations or provide default strategies.

  3. Method Injection Mismatches The configured method must exist in the composite class and accept the correct argument type. Fix: Verify method signatures and use PHPDoc types for clarity.

  4. Configuration Overrides Bundle configurations in strategy_injector.yaml are merged; later entries override earlier ones. Fix: Order configurations carefully or use unique keys.

  5. Archived Package Risks The package is archived; ensure no critical bugs exist or fork it if needed. Fix: Test thoroughly and consider alternatives like league/tactician for production.

Debugging Tips

  • Log Injected Strategies Add debug output in the composite’s constructor/method to verify injected strategies:

    public function __construct(array $strategies) {
        \Log::debug('Injected strategies:', $strategies);
    }
    
  • Validate YAML Syntax Use Symfony’s config validator or symfony/var-dumper to inspect parsed configurations:

    use Symfony\Component\DependencyInjection\ContainerInterface;
    $config = $container->getParameter('strategy_injector');
    
  • Check Autowiring Ensure the composite class is properly tagged or autowired in services.yaml:

    App\Strategy\CompositeFooStrategy:
        tags: ['strategy.injector.composite']
    

Extension Points

  1. Custom Strategy Resolvers Override the bundle’s resolver logic by extending StrategyInjector\Resolver\StrategyResolverInterface and binding it in the container.

  2. Dynamic Strategy Discovery Implement a custom compiler pass to discover strategies at runtime (e.g., from a database):

    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
  3. Strategy Metadata Add metadata (e.g., priority, enabled) to strategies via attributes or annotations and filter them in the composite:

    #[Strategy(priority: 100)]
    class HighPriorityStrategy implements FooStrategyInterface { ... }
    
  4. Integration with Other Bundles Combine with symfony/options-resolver for dynamic strategy configuration:

    use Symfony\Component\OptionsResolver\OptionsResolver;
    $resolver = new OptionsResolver();
    $resolver->setDefaults(['strategies' => []]);
    
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.
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php
trappistes/laravel-custom-fields
splash/sonata-admin
splash/metadata