Service Providers

Service Providers for bootstrapping services and registering bindings in Container

graph TD A[Application Start] --> B[Load Service Providers] B --> C{Deferred?} C -->|No| D[Register All] C -->|Yes| E[Register Only] D --> F[Boot All] E --> G[Wait for Service] G --> H[Lazy Load] H --> I[Register & Boot] F --> J[Application Ready] I --> J

Service Providers are classes that bootstrap services and dependencies in Laravel. They are the central point for bootstrapping application and manage all configuration, binding, and initialization logic.


Two Main Methods:


1. register(): For registering bindings in Service Container. This method should only do binding and not use other services because they may not be registered yet.


2. boot(): For accessing other services and performing configurations. This method runs after all providers are registered, so you can access other services.


Deferred Providers: Some Providers are only loaded when actually needed, not on every request. This is suitable for rarely used or resource-intensive services.


Uses:


  • Register bindings in Service Container
  • Register routes and route groups
  • Register view composers and view creators
  • Register event listeners and subscribers
  • Configure packages and third-party services
  • Register middleware and middleware groups
  • Configure database connections
  • Register custom validation rules

Examples

Creating Service Provider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class PaymentServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('PaymentGateway', function ($app) {
            return new StripePaymentGateway();
        });
    }
    
    public function boot()
    {
        // Access other services here
    }
}

A simple Service Provider that registers PaymentGateway as singleton.

Service Provider with Route Registration

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;

class ApiServiceProvider extends ServiceProvider
{
    public function register()
    {
        // Register bindings
    }
    
    public function boot()
    {
        Route::prefix('api')
            ->middleware('api')
            ->namespace('App\Http\Controllers\Api')
            ->group(base_path('routes/api.php'));
    }
}

In boot() you can register routes.

Service Provider with View Composers

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;

class ViewServiceProvider extends ServiceProvider
{
    public function boot()
    {
        View::composer('layouts.app', function ($view) {
            $view->with('categories', Category::all());
        });
        
        View::composer('*', function ($view) {
            $view->with('currentUser', auth()->user());
        });
    }
}

You can register view composers in boot().

Service Provider with Event Listeners

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Event;
use App\Events\OrderCreated;
use App\Listeners\SendOrderConfirmation;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        OrderCreated::class => [
            SendOrderConfirmation::class,
        ],
    ];
    
    public function boot()
    {
        Event::listen(OrderCreated::class, SendOrderConfirmation::class);
    }
}

You can register event listeners in boot().

Service Provider with Middleware Registration

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Http\Kernel;

class MiddlewareServiceProvider extends ServiceProvider
{
    public function boot(Kernel $kernel)
    {
        $kernel->pushMiddleware(\App\Http\Middleware\CustomMiddleware::class);
        
        $kernel->prependMiddleware(\App\Http\Middleware\FirstMiddleware::class);
        
        $kernel->appendMiddlewareToGroup('web', \App\Http\Middleware\WebMiddleware::class);
    }
}

You can register middleware in boot().

Service Provider with Custom Validation Rules

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;

class ValidationServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Validator::extend('phone', function ($attribute, $value, $parameters, $validator) {
            return preg_match('/^[0-9]{10}$/', $value);
        });
        
        Validator::replacer('phone', function ($message, $attribute, $rule, $parameters) {
            return str_replace(':attribute', $attribute, 'The :attribute must be a valid phone number.');
        });
    }
}

You can register custom validation rules in boot().

Service Provider with Database Configuration

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\DB;

class DatabaseServiceProvider extends ServiceProvider
{
    public function boot()
    {
        DB::listen(function ($query) {
            // Log all queries in development
            if (app()->environment('local')) {
                Log::info($query->sql, [
                    'bindings' => $query->bindings,
                    'time' => $query->time
                ]);
            }
        });
        
        // Set connection timeout
        config(['database.connections.mysql.options.connect_timeout' => 10]);
    }
}

You can configure database in boot().

Conditional Service Provider Registration

<?php

// In config/app.php
'providers' => [
    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    
    // Conditional registration
    ...(app()->environment('local') ? [
        App\Providers\DebugServiceProvider::class,
    ] : []),
],

// Or in Service Provider itself
class ConditionalServiceProvider extends ServiceProvider
{
    public function register()
    {
        if ($this->app->environment('production')) {
            $this->app->singleton('Service', ProductionService::class);
        } else {
            $this->app->singleton('Service', DevelopmentService::class);
        }
    }
}

You can conditionally register service providers.

Use Cases

  • Registering bindings for dependency injection
  • Registering routes for modular architecture
  • Configuring third-party packages
  • Registering event listeners and subscribers
  • Registering view composers for shared data
  • Registering custom validation rules
  • Configuring database connections
  • Registering middleware and middleware groups

Common Mistakes

  • Using services in register() that haven't been registered yet
  • Performing heavy operations in register() causing slow bootstrap
  • Forgetting to register provider in config/app.php
  • Using boot() for binding which should be in register()
  • Not using deferred providers for rarely used services
  • Registering routes in register() instead of boot()

Best Practices

  • In register() only do binding
  • Use boot() to access other services
  • Use deferred providers for rarely used services
  • Keep providers modular and focused
  • Use conditional registration for environment-specific providers
  • Document providers
  • Use service provider discovery for packages

Edge Cases

  • Circular dependency in service providers
  • Provider that throws exception in register()
  • Deferred provider that never loads
  • Provider requiring HTTP context
  • Provider in queue jobs which have different container instance

Performance Notes

  • Using deferred providers can reduce bootstrap time
  • Registering binding in register() is faster than boot()
  • Provider discovery in Laravel 11.x has performance improvements
  • Use conditional registration to reduce provider count
  • Perform heavy operations in boot(), not register()

Security Notes

  • Ensure providers follow security best practices
  • Use conditional registration for security-sensitive providers
  • Ensure sensitive bindings are properly done

Interview Points

  • What is the difference between register() and boot()?
  • When should you use deferred provider?
  • How can you register a service provider?
  • What should be done in register() and what in boot()?
  • What are the benefits of using service providers?
  • How can you do conditional provider registration?

Version Notes

  • Laravel 11.x: Improved performance in provider loading
  • Laravel 11.x: Better support for provider discovery
  • Laravel 10.x: Improved deferred provider resolution
  • Laravel 9.x: Improved provider caching