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

apie/service-provider-generator

Generate Laravel ServiceProvider classes from Symfony YAML service definitions. Keep framework-agnostic libraries in sync by maintaining a single service container registry, then output PHP source code you can write to a file (or eval if you must).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require apie/service-provider-generator
    

    Require the package in your project via Composer.

  2. Basic Usage Generate a Laravel service provider from a services.yaml file:

    php artisan apie:service-provider-generator path/to/services.yaml
    

    This creates a new service provider class in app/Providers/ with bindings and singleton configurations.

  3. First Use Case

    • Convert a Symfony services.yaml (e.g., from a legacy app or microservice) into a Laravel-compatible provider.
    • Example input (services.yaml):
      services:
          App\Services\MyService:
              arguments:
                  - '@App\Repositories\DataRepository'
              tags: ['app.service']
      
    • Output: A MyServiceProvider with bindings like:
      $this->app->singleton(MyService::class, function ($app) {
          return new MyService($app->make(DataRepository::class));
      });
      

Implementation Patterns

Usage Patterns

  1. Incremental Adoption

    • Use the generator to migrate Symfony services incrementally. Start with non-critical services, test, then expand.
    • Example workflow:
      # Generate for a subset of services
      php artisan apie:service-provider-generator services.yaml --services="App\Services\*"
      
  2. Integration with Laravel’s DI Container

    • Leverage Laravel’s built-in container methods (singleton(), bind(), tag()) for consistency.
    • Example: Use when() for conditional bindings:
      $this->app->when(MyService::class)
          ->needs(DataRepository::class)
          ->give(function ($app) { ... });
      
  3. Tagging and Aliasing

    • Map Symfony tags (e.g., app.service) to Laravel’s tag() method for service discovery:
      $this->app->tag([MyService::class], 'app.service');
      
    • Use --tags flag to auto-generate tagged bindings:
      php artisan apie:service-provider-generator services.yaml --tags
      
  4. Environment-Specific Configurations

    • Use Laravel’s config files (config/services.php) to override generated bindings:
      'bindings' => [
          MyService::class => \App\Services\MyService::class,
      ],
      
    • Pass --env flag to generate environment-aware providers:
      php artisan apie:service-provider-generator services.yaml --env=production
      

Workflows

  1. CI/CD Pipeline Integration

    • Add the generator as a pre-deployment step to ensure service providers are up-to-date:
      # .github/workflows/deploy.yml
      - run: php artisan apie:service-provider-generator config/services.yaml
      
  2. Testing Generated Providers

    • Mock the generated provider in tests using Laravel’s bind():
      $this->app->bind(MyService::class, function () {
          return Mockery::mock(MyService::class);
      });
      
  3. Customizing Output

    • Extend the generator’s ServiceProviderGenerator class to add pre/post-processing logic:
      // app/Console/Commands/CustomServiceProviderGenerator.php
      class CustomServiceProviderGenerator extends ServiceProviderGenerator {
          protected function customizeBinding(string $service, array $config): string {
              // Add custom logic (e.g., inject config)
              return parent::customizeBinding($service, $config);
          }
      }
      

Gotchas and Tips

Pitfalls

  1. Circular Dependencies

    • Symfony’s services.yaml may define circular dependencies (e.g., A depends on B, which depends on A). Laravel’s container will throw an exception.
    • Fix: Refactor dependencies or use lazy loading with bindIf():
      $this->app->bindIf(
          CircularService::class,
          function ($app) { return new CircularService($app->make(OtherService::class)); }
      );
      
  2. Type Safety

    • The generator assumes PHP 8.0+ type hints. If your services.yaml lacks type info, bindings may fail.
    • Fix: Add @var annotations or use instanceof checks:
      $this->app->bind('app.service', function ($app) {
          return $app->make(ServiceInterface::class);
      });
      
  3. Namespace Conflicts

    • Symfony services may use short class names (e.g., App\Services\Logger), but Laravel expects fully qualified names.
    • Fix: Use --namespace flag to auto-resolve or manually update the YAML:
      services:
          _defaults:
              autowire: true
              autoconfigure: true
              public: false
      
  4. Singleton vs. Non-Singleton

    • Symfony defaults to singletons, but Laravel requires explicit singleton() calls.
    • Fix: Use --strict flag to enforce singleton bindings or add manual overrides.

Debugging

  1. Dry Run Mode

    • Test generation without writing files:
      php artisan apie:service-provider-generator services.yaml --dry-run
      
  2. Verbose Output

    • Enable debug mode for detailed binding logs:
      php artisan apie:service-provider-generator services.yaml --verbose
      
  3. Validation Errors

    • Invalid YAML (e.g., missing services: root) will fail silently. Validate first:
      php artisan apie:validate-yaml services.yaml
      

Tips

  1. Leverage Laravel’s Helpers

    • Combine with collect() for dynamic bindings:
      collect($this->app['config']['services.bindings'])
          ->each(fn ($class, $alias) => $this->app->bind($alias, $class));
      
  2. Partial Generation

    • Generate only modified services using --changed:
      php artisan apie:service-provider-generator services.yaml --changed
      
  3. IDE Integration

    • Use PHPStorm’s "Regenerate PHPStorm Metadata" (Ctrl+Shift+R) after generation to update autocompletion.
  4. Performance

    • For large services.yaml, use --batch-size=50 to process bindings in chunks and avoid memory issues.
  5. Extending the Generator

    • Override ServiceProviderGenerator::generateBindings() to add custom logic (e.g., logging, caching):
      protected function generateBindings(array $services): string {
          Log::info('Generating bindings for: ' . count($services) . ' services');
          return parent::generateBindings($services);
      }
      
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
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