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

Di Extra Bundle Laravel Package

jms/di-extra-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation Add the bundle via Composer:

    composer require jms/di-extra-bundle
    

    Enable it in config/bundles.php (Symfony) or config/app.php (Laravel via Bridge):

    return [
        // ...
        JMS\DiExtraBundle\JMSDiExtraBundle::class => ['all' => true],
    ];
    
  2. Basic Setup Ensure your project uses annotations (Doctrine Annotations recommended). Install:

    composer require doctrine/annotations
    
  3. First Use Case Annotate a service to autowire dependencies:

    use JMS\DiExtraBundle\Annotation as DI;
    
    class MyService
    {
        /**
         * @DI\InjectParams({
         *     @DI\InjectParam("param1", service="app.service1"),
         *     @DI\InjectParam("param2", service="app.service2")
         * })
         */
        public function __construct($param1, $param2) {}
    }
    

    Clear cache:

    php artisan config:clear
    

Implementation Patterns

Common Workflows

  1. Autowiring via Annotations Replace manual bind() calls with annotations for cleaner DI:

    /**
     * @DI\Service("app.my_service")
     */
    class MyService {}
    
  2. Parameter Injection Inject complex parameters (e.g., configs, factories) without hardcoding:

    /**
     * @DI\InjectParams({
     *     @DI\InjectParam("config", service="app.config_loader")
     * })
     */
    public function __construct(ConfigLoader $config) {}
    
  3. Lazy Loading Defer service initialization:

    /**
     * @DI\LazyService
     */
    class HeavyService {}
    
  4. Tagged Services Group services for later retrieval:

    /**
     * @DI\Service("app.listener")
     * @DI\Tag("kernel.event_listener")
     */
    class MyEventListener {}
    
  5. Integration with Laravel Use Symfony Bridge to bridge annotations with Laravel’s container:

    $container->loadFromExtension('jms_di_extra', [
        'services' => [
            'app.my_service' => [
                'class' => MyService::class,
                'arguments' => ['%param%'],
            ],
        ],
    ]);
    

Pro Tips

  • Combine with Laravel Mixins: Use annotations for services while keeping Laravel’s bind() for framework-specific logic.
  • Priority Order: Annotations override manual bindings (use priority in @DI\Service to control order).
  • Testing: Mock annotated services by extending PHPUnit and overriding the container.

Gotchas and Tips

Pitfalls

  1. Cache Dependency

    • Issue: Annotations are compiled into cache. Forgetting to clear cache (php artisan config:clear) breaks changes.
    • Fix: Always clear cache after modifying annotated classes.
  2. Annotation Parser Conflicts

    • Issue: Conflicts with other annotation parsers (e.g., Doctrine ORM).
    • Fix: Explicitly load jms_di_extra after Doctrine’s parser in config/services.php:
      $container->loadFromExtension('doctrine', [/* ... */]);
      $container->loadFromExtension('jms_di_extra', [/* ... */]);
      
  3. Circular Dependencies

    • Issue: Annotations don’t prevent circular dependencies (Symfony’s container does).
    • Fix: Use @DI\LazyService or refactor to break cycles.
  4. Laravel-Specific Quirks

    • Issue: Laravel’s AppServiceProvider runs before Symfony’s container is fully initialized.
    • Fix: Defer annotation-based bindings to BootstrapServiceProvider or use register() in AppServiceProvider:
      public function register()
      {
          $this->app->register(JMS\DiExtraBundle\JMSDiExtraBundle::class);
      }
      

Debugging

  • Enable Debug Mode: Set jms_di_extra.debug to true in config to log annotation parsing.
  • Check Compiled Dumps: Inspect bootstrap/cache/services.yaml for generated service definitions.
  • Override Services: Temporarily bind a service manually to test:
    $this->app->bind('app.my_service', function () {
        return new MockMyService();
    });
    

Extension Points

  1. Custom Annotations Extend the bundle by creating your own annotations and integrating them via Symfony’s CompilerPass:

    # config/packages/jms_di_extra.yaml
    jms_di_extra:
        annotations:
            - 'App\Annotation\CustomAnnotation'
    
  2. Post-Processing Use jms_di_extra.post_process event to modify services after annotation parsing:

    $container->getCompiler()->addPostProcessor(
        new class implements ContainerAwareInterface {
            public function process(ContainerBuilder $container) {
                // Modify services here
            }
        }
    );
    
  3. Laravel Facades Bridge annotated services to Laravel facades:

    Facade::register('MyService', function () {
        return app('app.my_service');
    });
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware