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

Service Provider Bridge Bundle Laravel Package

bnf/service-provider-bridge-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Bundle Add the bundle to your composer.json:

    composer require bnf/service-provider-bridge-bundle
    

    Register it in config/bundles.php (Symfony 4+) or app/AppKernel.php (Symfony 3/4):

    // config/bundles.php
    return [
        // ...
        Bnf\Interop\ServiceProviderBridgeBundle\InteropServiceProviderBridgeBundle::class => ['all' => true],
    ];
    
  2. Define a Service Provider Create a class implementing Interop\Container\ServiceProviderInterface:

    use Interop\Container\ServiceProviderInterface;
    use Psr\Container\ContainerInterface;
    
    class MyServiceProvider implements ServiceProviderInterface
    {
        public function getService($id)
        {
            return new MyService();
        }
    }
    
  3. Register the Provider Declare it in the bundle constructor (Symfony 4+):

    use Bnf\Interop\ServiceProviderBridgeBundle\InteropServiceProviderBridgeBundle;
    use Interop\Container\ServiceProviderInterface;
    
    class MyBundle extends Bundle
    {
        public function __construct()
        {
            parent::__construct();
            $this->setServiceProvider(new MyServiceProvider());
        }
    }
    
  4. Access Services Fetch services via the Symfony container:

    $service = $container->get('my_service'); // If registered via `getService()` with ID 'my_service'
    

First Use Case

Scenario: You have a legacy or third-party library using container-interop/service-provider and need to integrate it into a Symfony app.

  1. Wrap the Provider Create a Symfony-compatible wrapper for the external provider:

    use Interop\Container\ServiceProviderInterface;
    
    class ExternalProviderWrapper implements ServiceProviderInterface
    {
        private $externalProvider;
    
        public function __construct(ExternalProvider $provider)
        {
            $this->externalProvider = $provider;
        }
    
        public function getService($id)
        {
            return $this->externalProvider->get($id);
        }
    }
    
  2. Register in Bundle Attach the wrapper to your bundle:

    public function __construct()
    {
        $this->setServiceProvider(new ExternalProviderWrapper(new ExternalProvider()));
    }
    
  3. Use in Controllers Inject the service directly into Symfony services/controllers:

    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    class MyController
    {
        public function __construct(private ContainerInterface $container)
        {
        }
    
        public function index()
        {
            $externalService = $this->container->get('external_service_id');
            // ...
        }
    }
    

Implementation Patterns

Workflows

  1. Hybrid Container Integration Use the bridge to unify container-interop providers with Symfony’s DI:

    // In a service class
    public function __construct(
        private ContainerInterface $container,
        private ExternalServiceProvider $externalProvider
    ) {
        // Register external provider via bridge
        $this->container->get('interop_bridge')->addProvider($this->externalProvider);
    }
    
  2. Dynamic Provider Loading Load providers conditionally (e.g., based on environment):

    public function build(ContainerBuilder $container)
    {
        if ($container->getParameter('feature.enabled')) {
            $this->setServiceProvider(new FeatureServiceProvider());
        }
    }
    
  3. Service Aliasing Map container-interop IDs to Symfony’s naming conventions:

    // In MyServiceProvider
    public function getService($id)
    {
        if ($id === 'legacy_service') {
            return new SymfonyCompatibleService();
        }
        throw new \OutOfBoundsException("Service $id not found.");
    }
    

Integration Tips

  1. Leverage Symfony’s Compiler Passes Automate provider registration:

    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    class RegisterProvidersPass implements CompilerPassInterface
    {
        public function process(ContainerBuilder $container)
        {
            $definition = $container->findDefinition('interop_bridge');
            $definition->addMethodCall('addProvider', [new MyServiceProvider()]);
        }
    }
    
  2. Combine with Symfony’s Autowiring Autowire services from container-interop providers:

    # config/services.yaml
    services:
        App\Service\MyService:
            arguments:
                $externalService: '@external_service_id' # Resolved via bridge
    
  3. Testing Providers Mock providers in tests:

    $container = new Container();
    $container->addProvider(new class implements ServiceProviderInterface {
        public function getService($id) {
            return $this->container->get('test.service');
        }
    });
    

Gotchas and Tips

Pitfalls

  1. Service ID Conflicts

    • Issue: Duplicate service IDs between Symfony and container-interop providers.
    • Fix: Use unique prefixes or aliases:
      // In MyServiceProvider
      public function getService($id) {
          return new Service(['id' => 'interop_' . $id]);
      }
      
  2. Circular Dependencies

    • Issue: container-interop providers may not handle circular dependencies like Symfony’s DI.
    • Fix: Refactor providers to avoid circular getService() calls or use lazy-loading.
  3. Bundle Lifecycle Mismatch

    • Issue: Providers may be registered too early/late in the kernel lifecycle.
    • Fix: Use KernelEvents::PRE_BOOT or POST_BOOT to control timing:
      $dispatcher->addListener(KernelEvents::PRE_BOOT, function () {
          $this->setServiceProvider(new EarlyProvider());
      });
      

Debugging

  1. Check Provider Registration Dump registered providers:

    $bridge = $container->get('interop_bridge');
    var_dump($bridge->getProviders()); // Array of registered ServiceProviderInterface
    
  2. Service Resolution Logs Enable Symfony’s debug mode to trace missing services:

    APP_DEBUG=1 php bin/console debug:container my_service
    
  3. Interop Compliance Validate providers against container-interop specs:

    composer require --dev container-interop/container-interop
    ./vendor/bin/phpcs --standard=ContainerInterop src/
    

Extension Points

  1. Custom Provider Factories Dynamically create providers based on config:

    $factory = new ProviderFactory($container->getParameter('providers'));
    $this->setServiceProvider($factory->create('database_provider'));
    
  2. Provider Prioritization Override existing providers:

    $bridge->addProvider(new OverrideProvider(), 100); // Higher priority
    
  3. PSR-11 Container Integration Expose the bridge as a PSR-11 container:

    use Interop\Container\ContainerInterface;
    
    class Psr11Bridge implements ContainerInterface
    {
        public function get($id)
        {
            return $this->bridge->getService($id);
        }
        // ...
    }
    

Config Quirks

  1. Bundle Configuration Extend bundle config via config/packages/interop_service_provider_bridge.yaml:

    interop_service_provider_bridge:
        providers:
            - App\Provider\FirstProvider
            - App\Provider\SecondProvider
    

    Note: Requires custom compiler pass to parse this.

  2. Environment-Specific Providers Use %kernel.environment% to switch providers:

    $this->setServiceProvider(
        $container->getParameter('kernel.environment') === 'test'
            ? new TestServiceProvider()
            : new ProdServiceProvider()
    );
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor