Laravel Service Provider in Simple English

Sam Ngu
4 min readNov 29, 2021

I would admit, when I first started to learn Laravel, Service Provider was one of the most confusing topics of all. Also, watch this tutorial on my Youtube Channel:

Photo by AbsolutVision on Unsplash

Key Concepts

First thing first, let’s clarify some of the concepts.

Services in Laravel are classes that provide features in our app. For example, if we are building a share riding app, we might need a Geolocation class / service that would provide geolocation information, or a Map service to retrieve the address of a place.

Service Container is a box that is always attached to our app. The container is supposed to hold Services in our app.

However, Services that we created in our app are just normal PHP classes. They are not connected to the Service Container by default. It is our job as a developer to bind these Services to the container.

Services are not connected to our app instance by default

But how can we bind the Services into the Container?

In general, there are 2 ways.

  1. Using the bind() method from our $app instance.
    We can explicitly call the bind() method or singleton() method on the $app instance. Typically we would call these 2 methods in /bootstrap/app.php or /app/Http/Kernel.php or in AppServiceProvider .
  2. Using Service Provider
    Alternatively, we will create a Service Provider class and register our Service in there.

Okay here is how Service Provider works

In summary, Service Provider is a class that contains the logic on how to instantiate a Service in Laravel. Once we defined a Service Provider, the service will be registered into the Service Container. If we need an instance of the Service, we can just resolve it out from the Service Container.

But why can’t we just use the ‘new’ keyword to instantiate a class?

Fair point. Here’s the thing, using Service Provider can make our life much easier. Let’s go back to our previous example, where we are building a ride-sharing app. We need 3 services:

  1. Geolocation to retrieve the geocoordinates.
  2. Map to retrieve the information about a place.
  3. Satellite to communicate with GPS and pinpoint the exact location.

Now, Geolocation needs the other 2 services ( Map and Satellite )to work correctly. That means every time when we need to instantiateGeolocation , we also need to create new instances of Map and Satellite , which is rather tedious. The code will look something like this:

class Satellite {
// ...
}class Map{ // ...}class Geolocation{ public function __construct(Map $map, Satellite $satellite)
{
// ...
}
}

And to instantiate Geolocation :

$map = new Map();
$satellite = new Satellite();
$geolocation = new Geolocation($map, $satellite);

As you can see above, we need to instantiate Map and Satellite first, before we can create a new Geolocation instance. If we need Geolocation in 100 places across our project, it will be a pain in the ass.

Service Provider to the Rescue

As I mentioned earlier, once we created a Service Provider, the Service should be registered into the Service Container. Since we have put the instructions on how to instantiate the Geolocation class in its Service Provider, now when we resolve the Service from the container, Laravel will simply run the logic to create the Service.

I will show you what I meant.

The class structure of Service Provider:

To create a Service Provider, you can simply run php artisan make:provider <your-service-provider-name> . The Service Provider will appear in app/Providers .

There are 2 primary methods in every Service Provider.

The register() method

This is where we will tell Laravel how to instantiate our Service, and the place where we will bind the Service into the Service Container. In the example of Geolocation , we may want to do something similar to this:

Declaring the definition of how Laravel should create the Service when resolved from the Service Container

From the snippet above, we can see that we are calling the bind() method to bind the Geolocation Service into our Service Container. The callback function is where we will tell Laravel the details on how we can instantiate the Geolocation class.

The boot() method

Laravel will call the boot() method after every single Service Provider is registered. That means we have access to all of the Services in our app inside the boot() method. There are no hard rules on what to put inside the boot() method, but generally, we will put things like Event Listener or code that requires other Services.

Registering the Service Provider

Even we have created the Service Provider, it won’t just work. We will need to register our Service Provider in the /config/app.php config file, under the ‘provider’ key.

Registering Service Provider

Once we are done, we can now resolve the Geolocation Service from the Container by using the global app() function.

$geolocation = app(\App\Providers\GeolocationServiceProvider::class);
// ...

Isn’t that much neater than manually instantiating the Services?

--

--