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

Container Laravel Package

league/container

league/container is a lightweight PSR-11 dependency injection container for PHP. Define entries, factories, and autowiring-friendly services to manage application dependencies cleanly, with modern PHP support and solid tooling for testing and analysis.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require league/container
    
  2. Basic Usage:

    use League\Container\Container;
    
    $container = new Container();
    $container->add(MyService::class, MyService::class); // Register a concrete
    $service = $container->get(MyService::class); // Resolve
    
  3. First Use Case:

    • Replace Laravel's built-in container with league/container for lightweight DI in a module or standalone script:
      $container = new Container();
      $container->add(\App\Services\UserService::class, \App\Services\UserService::class);
      $userService = $container->get(\App\Services\UserService::class);
      

Where to Look First

  • PSR-11 Compliance – The package adheres to PSR-11, so familiarize yourself with get(), has(), and set() methods.
  • Attribute Resolution – Use #[Inject] and #[Resolve] for dependency injection without manual registration.
  • Events – Hook into lifecycle events like BeforeResolveEvent or ServiceResolvedEvent for custom logic.

Implementation Patterns

Core Workflows

  1. Manual Registration:

    $container->add(
        \App\Contracts\LoggerInterface::class,
        \App\Services\FileLogger::class
    );
    
    • Use for explicit control over dependencies.
  2. Attribute-Based Resolution (Laravel-like auto-wiring):

    #[Inject]
    public function __construct(private UserRepository $users) {}
    
    • Enable via ReflectionContainer delegate:
      $container->addDelegate(new \League\Container\ReflectionContainer());
      
  3. Service Providers:

    $container->addServiceProvider(new class implements \League\Container\ServiceProviderInterface {
        public function provides(): array { return [UserRepository::class]; }
        public function register(): void {
            $this->container->add(UserRepository::class, UserRepository::class);
        }
    });
    
    • Group related registrations (e.g., database, logging).
  4. Shared vs. Non-Shared:

    $container->addShared(MyService::class, MyService::class); // Singleton
    $container->add(MyService::class, MyService::class);       // New instance per request
    

Integration Tips

  • Laravel Compatibility: Replace Laravel’s container in a module by binding to the same interfaces:

    $container->add(\Illuminate\Contracts\Container\Container::class, $laravelContainer);
    

    Use league/container for lightweight logic while leveraging Laravel’s ecosystem.

  • Event-Driven Extensions: Modify resolved services dynamically:

    $container->listen(
        \League\Container\Events\ServiceResolvedEvent::class,
        fn($event) => $event->getService()->setConfig($event->getContainer()->get('config'))
    );
    
  • Tagging for Collections:

    $container->addTag(MyService::class, 'api');
    $apiServices = $container->getTagged('api'); // Array of tagged services
    
  • Delegate Containers: Chain containers for modularity:

    $delegate = new \League\Container\Container();
    $delegate->add(\App\Services\Cache::class, \App\Services\RedisCache::class);
    $container->addDelegate($delegate);
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies:

    • The container throws ContainerException with actionable guidance if a class has unresolved constructor dependencies.
    • Fix: Restructure dependencies or use lazy resolution with afterResolve().
  2. Overwriting Definitions:

    • Disabled by default for safety. Enable with:
      $container->allowOverwrite(true);
      
    • Risk: Accidental redefinition of singletons.
  3. Attribute Resolution Quirks:

    • Union types (e.g., string|int) are not auto-wired. Register manually or use #[Resolve] with explicit types.
  4. Event System Performance:

    • Events are lazily initialized (created only when listeners exist). Avoid registering listeners for events you don’t use.
  5. ReflectionContainer Caching:

    • Enable caching for performance:
      $reflection = new \League\Container\ReflectionContainer();
      $reflection->setCache(new \League\Container\Cache\FileCache(__DIR__.'/cache'));
      $container->addDelegate($reflection);
      

Debugging Tips

  • Inspect Definitions:
    $definition = $container->getDefinition(MyService::class);
    var_dump($definition->getConcrete());
    
  • Check Registered Services:
    var_dump($container->getIds()); // All registered IDs
    
  • Enable Strict Mode:
    $container->setAutoResolve(false); // Disable auto-resolution of non-registered classes
    

Extension Points

  1. Custom Argument Resolvers: Override League\Container\Argument\ArgumentResolverInterface to handle custom types (e.g., DateTime from strings).

  2. Definition Modifiers: Use afterResolve() to post-process services:

    $container->afterResolve(MyService::class, fn($service) => $service->configure());
    
  3. Bootable Service Providers: Load providers eagerly:

    $container->addServiceProvider(new class implements \League\Container\BootableServiceProviderInterface {
        public function boot(): void { /* Setup */ }
        public function register(): void { /* Bindings */ }
    });
    $container->boot();
    
  4. Custom Exceptions: Extend \League\Container\Exception\ContainerException for domain-specific errors.

Laravel-Specific Quirks

  • Binding Interfaces: Laravel’s bind() maps to add() in league/container. Use addShared() for singletons.
  • Contextual Binding: Not natively supported. Use afterResolve() or event listeners for dynamic binding.
  • Tagged Services: Laravel’s tag() maps to addTag() in league/container.

Performance Notes

  • Avoid Over-Registration: Register only what’s needed to minimize reflection overhead.
  • Use Delegates: Offload reflection to ReflectionContainer for auto-wiring.
  • Cache Definitions: Enable caching in ReflectionContainer for repeated resolutions.

```markdown
### Example: Migrating from Laravel to League/Container
```php
// Laravel-style binding
$container->add(
    \App\Contracts\UserRepository::class,
    \App\Repositories\EloquentUserRepository::class
);

// Laravel-style singleton
$container->addShared(
    \App\Contracts\Cache::class,
    \App\Services\RedisCache::class
);

// Laravel-style tagging
$container->addTag(\App\Services\ApiService::class, 'api');

// Laravel-style context binding (workaround)
$container->listen(
    \League\Container\Events\BeforeResolveEvent::class,
    fn($event) => match ($event->getId()) {
        'user.repository' => $event->setConcrete(\App\Repositories\CacheUserRepository::class),
        default => null,
    }
);
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope