Laravel Service Provider

Advertisements

Overview

If you‘ve ever worked on the Laravel framework, you will listen regarding server container and service provider. They are the main part of the Laravel framework and do all huge tasks when your application runs.

Service container

The Laravel service container is a strong tool for handling class dependencies and implementing dependency injection.

Advertisements

Reference: https://laravel.com/docs/5.6/container#introduction

In the most simplistic way to explain service container, we can understand that it is a box that contains many components’ bindings, and they are served as required everywhere the application.

Service provider

Service providers are the focal place of every Laravel application bootstrapping. Your application, as well as every of Laravel’s core services are bootstrapped via service providers.

Reference : https://laravel.com/docs/5.6/providers#introduction

So whenever you need to include a service into other services, you can add it within constructor or method, and it’s included automatically from service container by the service provider.

Let’s have a look at a quick example to explain it.

class MyClass{
   public function __construct(MyService $my_service)
   {
        $my_service->doMyThing();
   }
}

As you can see, the MyClass requires an instance of MyService to instantiate itself. So essentially, it has a yoke that needs to be included. Laravel makes this automatically by examining into the service container and adding the relevant dependency.

It seems excellent, doesn’t it? There is no magic here, you can see at the contents of file `config/app.php`. You’ll get an array which managed to maintain all service providers, These service providers will be loaded while the bootstrapping of the Laravel app.

'providers' => [    /*
    * Laravel Framework Service Providers...
    */
   Illuminate\Auth\AuthServiceProvider::class,
   Illuminate\Broadcasting\BroadcastServiceProvider::class,
   Illuminate\Bus\BusServiceProvider::class,
   Illuminate\Cache\CacheServiceProvider::class,
   Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
   Illuminate\Cookie\CookieServiceProvider::class,
   Illuminate\Database\DatabaseServiceProvider::class,
   Illuminate\Encryption\EncryptionServiceProvider::class,
   Illuminate\Filesystem\FilesystemServiceProvider::class,
   Illuminate\Foundation\Providers\FoundationServiceProvider::class,
   Illuminate\Hashing\HashServiceProvider::class,
   Illuminate\Mail\MailServiceProvider::class,
   Illuminate\Notifications\NotificationServiceProvider::class,
   Illuminate\Pagination\PaginationServiceProvider::class,
   Illuminate\Pipeline\PipelineServiceProvider::class,
   Illuminate\Queue\QueueServiceProvider::class,
   Illuminate\Redis\RedisServiceProvider::class,
   Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
   Illuminate\Session\SessionServiceProvider::class,
   Illuminate\Translation\TranslationServiceProvider::class,
   Illuminate\Validation\ValidationServiceProvider::class,
   Illuminate\View\ViewServiceProvider::class,
    /*
    * Application Service Providers...
    */
   App\Providers\AppServiceProvider::class,
   App\Providers\AuthServiceProvider::class,
   App\Providers\EventServiceProvider::class,
   App\Providers\RouteServiceProvider::class,
    /**
    * Custom Provider
    */
],

Create service provider

According to Laravel official document, you can also create your service provider by running following cli

php artisan make:provider MyServiceProvider

Every service providers extend the Illuminate\Support\ServiceProvider class. Most service providers hold a register and a boot method. In the register method, you should only bind things within the service container. You should never try to register any event listeners, routes, or any other section of functionality inside the register method.

Reference: https://laravel.com/docs/5.6/providers#writing-service-providers

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class MyServiceProvider extends ServiceProvider{
    public function boot()
    {
     //
    }    public function register()
    {
     //
    }
}

As you notice, there are 2 essential methods in your class, boot and register.

The register method is the spot where you hold all your service container bindings.

On the other hand, the boot method is the spot where you can handle already registered services via the register method to do wonderful things, it implies this method is requested after all other service providers have been registered.

The register method

There is no necessary to join classes inside the container if they do not depend on any interfaces. The container does not require to be instructed on how to build those objects, since it can automatically determine those objects using reflection.

Reference : https://laravel.com/docs/5.6/container#binding

So you don’t require to build your service provider if you don’t have an interface. Laravel will use reflection. That’s what occurs in earlier example with MyClass and MyService.

Now, we go leading with an instance which utilises interface, so let build your interface.

<?php
namespace App\Service;
interface MyServiceInterface
{
    public function doMyThing();
}

And the service

<?php
namespace App\Service;
class MyService implements MyServiceInterface
{
    public function doMyThing()
    {
        echo ‘do my thing !!!’;
    }
}

After that, instead of binding a class, we’ll bind an interface.

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class MyServiceProvider extends ServiceProvider
{
    public function boot()
    {
        //
    }
    
    public function register()
    {
        $this->app->bind(‘App\Service\MyServiceInterface’, ‘App\Service\MyService’);
    }
}

Add your service provider into file config/app.php

‘providers’ => [
    ……
    /**
    * Custom Provider
    */    App\Providers\MyServiceProvider::class,
],

Let create controller to use your service

<?php
namespace App\Http\Controllers;
use App\Service\MyServiceInterface;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class MyController extends Controller
{
     public function myFunc(MyServiceInterface $my_service)
     {
         $my_service->doMyThing();
         return new Response();
     }
}

Using service provider, it’s adjustable to modify service added to others. Functions of the user are fixed.

And yoke injection decreases coupling within a class and its yoke. So we can able to implement a class and its yoke at the same time.

For a example, you add ProductService which provides function getAllProduct() into StudentController by using the constructor method. You can create MockStudentService with hardcoded data to implement StudentController, and the other one can implement StudentService at the same time.

By managing the service provider, you can modify class added instantly and smoothly.

The boot method

If you need to register a view composer inside our service provider, this is a ideal spot to do such

/**
* Bootstrap services.
*
* @return void
*/public function boot()
{
    View::composer(
        ‘profile’, ‘App\Http\ViewComposers\ProfileComposer’
    );
}

Conclusion

We simply go through the talk about the service provider, it’s an essential component of the Laravel framework. And we additionally have some samples of the service provider.

Advertisements