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 Laravel Package

yiisoft/di

PSR-11 compatible dependency injection container for PHP 8.1+. Supports autowiring plus constructor, method and property injection, aliasing, service providers, delegated/composite containers, circular reference detection, and state reset for long-running workers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require yiisoft/di
    

    Add to composer.json under autoload-dev if using for testing:

    "yiisoft/di": "^1.0"
    
  2. Basic Container Initialization:

    use Yiisoft\Di\Container;
    
    $container = new Container();
    
  3. First Use Case: Define a service and resolve it:

    // Define a service
    $container->set('service', fn() => new MyService());
    
    // Resolve and use
    $service = $container->get('service');
    $service->doSomething();
    
  4. Where to Look First:


Implementation Patterns

Core Workflows

  1. Service Registration:

    • Closure-based:
      $container->set(MyService::class, fn() => new MyService());
      
    • Class-based (auto-instantiation):
      $container->set(MyService::class, MyService::class);
      
    • Singleton vs. Transient:
      $container->set(MySingleton::class, MySingleton::class, ['shared' => true]);
      
  2. Dependency Resolution:

    • Constructor Injection:
      $container->set(MyService::class, fn($container) => new MyService($container->get(AnotherService::class)));
      
    • Method Injection (via call):
      $container->set('handler', fn($container) => [
          'method' => 'handle',
          'object' => $container->get(RequestHandler::class),
          'params' => [$container->get(Request::class)],
      ]);
      
  3. Configuration Injection:

    • Use config parameter in set():
      $container->set(MyConfigurableService::class, MyConfigurableService::class, [
          'config' => ['timeout' => 30, 'retries' => 3],
      ]);
      
  4. Grouping Services:

    • Define service groups for modular apps:
      $container->setGroups([
          'auth' => [
              UserRepository::class,
              AuthService::class,
          ],
      ]);
      
  5. Integration with Laravel:

    • Replace Laravel’s container (not recommended for production) or use alongside:
      $yiisoftContainer = new Container();
      $yiisoftContainer->set('app', fn() => new App($yiisoftContainer->get('config')));
      

Common Patterns

  • Factory Services:
    $container->set(FactoryService::class, fn($container) => new FactoryService(
        $container->get(Database::class),
        $container->get(Cache::class)
    ));
    
  • Dynamic Resolution: Use has() to check for service existence before resolving:
    if ($container->has('optional-service')) {
        $service = $container->get('optional-service');
    }
    
  • Contextual Binding: Override services per context (e.g., testing):
    $container->set(MyService::class, TestMyService::class, ['shared' => false]);
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies:

    • Symptom: CircularReferenceException during resolution.
    • Fix: Restructure dependencies or use lazy-loading with closures:
      $container->set(CircularService::class, fn($container) => new CircularService(
          $container->get(OtherService::class) // Resolved lazily
      ));
      
  2. Shared vs. Non-Shared Instances:

    • Gotcha: Forgetting shared: true can lead to duplicate instances.
    • Tip: Default is false; explicitly set for singletons.
  3. Configuration Overrides:

    • Gotcha: Config passed to set() is merged, not replaced. Use config: [] to clear:
      $container->set(MyService::class, MyService::class, ['config' => []]);
      
  4. PSR-11 Compliance:

    • Gotcha: Non-PSR-11 methods (e.g., make()) may not work with all PSR-11 consumers.
    • Tip: Stick to get(), has(), and set().
  5. Namespace Collisions:

    • Gotcha: Using class names as keys can conflict with fully qualified names.
    • Tip: Prefer string keys (e.g., 'app.services.user-repo') for clarity.

Debugging

  1. Inspect Container Contents:
    $services = $container->getDefinitions();
    dump($services);
    
  2. Enable Debug Mode:
    $container->setDebug(true); // Logs resolution steps
    
  3. Handle Resolution Errors:
    • Catch ContainerException for missing or invalid services:
      try {
          $container->get('nonexistent-service');
      } catch (ContainerException $e) {
          Log::error($e->getMessage());
      }
      

Tips

  1. Use Interfaces for Abstraction:
    $container->set(LoggerInterface::class, MonologLogger::class);
    
  2. Leverage Autowiring: Enable in Yii or manually resolve by class name:
    $container->get(MyService::class); // Works if registered as class key
    
  3. Extend Container: Create a custom container class:
    class AppContainer extends Container {
        public function __construct() {
            parent::__construct();
            $this->setDefaults([
                'app.name' => 'MyApp',
            ]);
        }
    }
    
  4. Performance:
    • Pre-resolve heavy services during bootstrapping.
    • Use shared: true for expensive-to-initialize services.
  5. Testing:
    • Replace services easily in tests:
      $container->set(MyService::class, TestMyService::class);
      
    • Use ContainerInterface for mocking in unit tests.

Extension Points

  1. Custom Definitions: Extend Definition class to add metadata or validation:
    class CustomDefinition extends Definition {
        public function __construct(array $config = []) {
            parent::__construct($config);
            $this->set('custom-meta', $config['meta'] ?? null);
        }
    }
    
  2. Compiler Passes: Use Compiler to pre-process definitions (e.g., for Yii modules):
    $compiler = new Compiler($container);
    $compiler->compile();
    
  3. Event Dispatching: Listen to Container::RESOLVING and Container::RESOLVED events for interception:
    $container->on(Container::RESOLVING, fn($event) => {
        if ($event->getService() === MyService::class) {
            $event->setService(new InterceptedMyService());
        }
    });
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests