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

Services Laravel Package

baks-dev/services

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation Add the package via Composer:

    composer require baks-dev/services
    

    Ensure your project meets the PHP 8.4+ requirement and Laravel 10.x+ compatibility.

  2. Publish Configuration Publish the default config to customize service definitions:

    php artisan vendor:publish --provider="BaksDev\Services\ServicesServiceProvider" --tag="services-config"
    

    This generates config/services.php. Modify it to define your services:

    'services' => [
        'payment' => [
            'class' => \App\Services\PaymentService::class,
            'enabled' => env('PAYMENT_SERVICE_ENABLED', true),
            'config' => [
                'api_key' => env('PAYMENT_API_KEY'),
            ],
        ],
    ],
    
  3. Register the Service Provider Ensure the provider is registered in config/app.php under providers:

    BaksDev\Services\ServicesServiceProvider::class,
    
  4. First Use Case: Resolving a Service Resolve and use a service in a controller or command:

    use BaksDev\Services\Facades\ServiceManager;
    
    public function processPayment()
    {
        $paymentService = ServiceManager::get('payment');
        $result = $paymentService->charge(100.00);
        return response()->json($result);
    }
    
  5. Verify with Tests Run the provided test group to ensure basic functionality:

    php bin/phpunit --group=services
    

Implementation Patterns

Service Registration Patterns

  1. Config-Driven Registration Define services in config/services.php for static, environment-driven services:

    'services' => [
        'logging' => [
            'class' => \App\Services\LoggingService::class,
            'config' => [
                'channel' => env('LOG_CHANNEL', 'stack'),
            ],
        ],
    ],
    

    Resolve via:

    $logger = ServiceManager::get('logging');
    
  2. Dynamic Registration Register services programmatically (e.g., for tenant-specific services):

    ServiceManager::register('tenant_'. $tenantId, function () use ($tenantId) {
        return new TenantService($tenantId);
    });
    
  3. Service Factories Use factories for complex service initialization:

    ServiceManager::register('analytics', function () {
        return app()->makeWith(\App\Services\AnalyticsService::class, [
            'config' => config('services.analytics'),
        ]);
    });
    

Dependency Injection Patterns

  1. Constructor Injection Inject ServiceResolver into classes for type-safe resolution:

    use BaksDev\Services\ServiceResolver;
    
    class OrderService {
        public function __construct(
            private ServiceResolver $resolver
        ) {}
    
        public function createOrder()
        {
            $payment = $this->resolver->resolve('payment');
            $payment->process();
        }
    }
    
  2. Method-Level Resolution Resolve services on-demand within methods:

    public function sendNotification()
    {
        $notifier = ServiceManager::get('notifications');
        $notifier->send('email', $user->email);
    }
    
  3. Service Chaining Chain services for workflows (e.g., payment → shipping):

    $payment = ServiceManager::get('payment');
    $shipping = ServiceManager::get('shipping');
    
    $payment->charge($amount);
    $shipping->process($order);
    

Integration with Laravel Ecosystem

  1. Service Providers Extend the package’s ServicesServiceProvider for custom logic:

    namespace App\Providers;
    
    use BaksDev\Services\ServicesServiceProvider as BaseProvider;
    
    class ServicesProvider extends BaseProvider {
        public function register()
        {
            parent::register();
            // Custom registrations
        }
    }
    
  2. Events and Listeners Trigger events when services are resolved or registered:

    // In a service class
    public function __construct() {
        event(new ServiceResolved($this));
    }
    
  3. Middleware for Services Use middleware to wrap service calls (e.g., logging, rate-limiting):

    ServiceManager::extend('payment', function ($service) {
        return new RateLimitedService($service);
    });
    
  4. Service Caching Cache resolved services to improve performance:

    ServiceManager::cacheServices(true);
    

Gotchas and Tips

Common Pitfalls

  1. Service Not Found

    • Issue: ServiceManager::get('unknown_service') throws an exception.
    • Fix: Ensure the service is registered in config/services.php or via ServiceManager::register().
    • Debug: Check config('services') to verify service definitions.
  2. Circular Dependencies

    • Issue: Services A and B depend on each other, causing infinite loops.
    • Fix: Refactor to use interfaces or resolve dependencies at a higher level.
  3. Configuration Overrides

    • Issue: Local .env values are ignored.
    • Fix: Ensure config/services.php uses env() correctly:
      'config' => [
          'api_key' => env('SERVICE_API_KEY', 'default'),
      ],
      
  4. PHP 8.4+ Features

    • Issue: Using attributes or enums may cause compatibility issues.
    • Fix: Test with php -v and adjust if using experimental features.
  5. Service Lifecycle Conflicts

    • Issue: Singleton services are recreated on each request.
    • Fix: Explicitly configure lifecycle in config/services.php:
      'services' => [
          'cache' => [
              'class' => \App\Services\CacheService::class,
              'lifecycle' => 'singleton', // or 'transient'
          ],
      ],
      

Debugging Tips

  1. Enable Debug Logging Add this to config/services.php:

    'debug' => env('APP_DEBUG', false),
    

    Logs service resolution to storage/logs/laravel.log.

  2. Inspect Resolved Services Dump resolved services for debugging:

    $service = ServiceManager::get('payment');
    dd($service); // Inspect instance
    
  3. Test Service Isolation Use Laravel’s service container to mock services in tests:

    $this->app->instance('payment', MockPaymentService::class);
    

Extension Points

  1. Custom Service Resolvers Extend ServiceResolver to add logic (e.g., tenant-aware resolution):

    namespace App\Services;
    
    use BaksDev\Services\ServiceResolver as BaseResolver;
    
    class TenantAwareResolver extends BaseResolver {
        public function resolve($id)
        {
            $tenantId = auth()->tenant()->id;
            return parent::resolve("tenant_{$tenantId}_{$id}");
        }
    }
    
  2. Service Decorators Wrap services to add cross-cutting concerns (e.g., logging):

    ServiceManager::extend('payment', function ($service) {
        return new LoggedService($service);
    });
    
  3. Dynamic Service Discovery Auto-discover services in a services/ directory:

    ServiceManager::discoverServices(app_path('Services'));
    

Configuration Quirks

  1. Priority Order Services registered via ServiceManager::register() override config-defined services.

  2. Environment-Specific Configs Use config/services.php to load environment-specific configs:

    'services' => [
        'payment' => [
            'config' => config("services.payment.{$app->environment()}"),
        ],
    ],
    
  3. Fallback Services Define fallback services for disabled services:

    'services' => [
        'analytics' => [
            'enabled' => false,
            'fallback' => 'null_service', // Resolves to a no-op service
        ],
    ],
    

Performance Considerations

  1. Avoid Over-Resolution Cache resolved services if they are expensive to initialize:

    ServiceManager::cacheServices(true);
    
  2. Lazy Loading Use ServiceResolver::resolveLazy() for deferred initialization:

    $service = $this->resolver->resolveLazy('heavy_service');
    $service->execute(); // Initializes on first use
    
  3. Service Warmup Pre-resolve critical services during boot:

    public function boot()
    {
        ServiceManager::get('payment'); // Warmup
    }
    
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