Laravel Service Provider Example
Making sense of Laravel Service Providers and Service Containers
I’ve read the service provider docs several times and I was always left with a vague understanding. Maybe a new explanation will be helpful? Here goes.
10,000 foot view
Laravel’s service providers are a little more than, but very much concerned with the concept of dependency injection. Here’s a non-academic description of dependency injection:
Dependency injection is sticking a required value in the parameter of a constructor or a setter method.
If a dependency that you’re injecting is simple has no dependencies of itself, this is no problem. But sometimes, your dependencies need a more hands-on approach to their instantiation.
The service container is where you would put the rules for making an instance of class that is being auto-loaded.
The service provider is a place where you can put the service container code.
The Service Provider does some other stuff too.
An example
Here’s a class that takes in a dependency.
In the above code we have a class whose constructor expects a FaceService
object. Our use
statement above shows where it’s located. Because Laravel is awesome, it will autoload the FaceService
class.
In many cases, this works great, but if we try to use our code, we will see this error: Unresolvable dependency resolving [Parameter #0 [ <required> $apiKey ]] in class App\Services\FaceService
Why?
The
FaceService
has specific dependencies of its own. This is why we need to use the Service Container.
Here’s the constructor of the face service.
So our dependency is an api key. It could be anything… another object… whatever. But if we inject this FaceServcice
depency into our controller, we need to ensure that the FaceService
is able to be instantiated correctly.
That’s where the Service Container comes into play.
The Service Container helps us set up our dependency
Here, we take advantage of the service container:
The above code says that when App\Services\FaceService
is going to be auto-loaded…. do stuff. In our case, we want to instantiate a new FaceService
object with our API key.
Since the first parameter in the bind method is a string, you can’t use the short version of the classname. You gotta send the whole path a la App\Services\FaceService
.
Now by binding to the service container, Laravel knows how to auto-load FaceService
.
This code lives in the Service Provider
You saw the Service Container code above but I didn’t say where to put it. It goes in a Service Provider. And specifically, it goes into the register
mehod.
You can create a new Service Provider by copying an existing one or using php artisan make:provider ProviderName
|
|
The above code contains our code that binds to the service containe, it’s wrapped nicely inside the register
method.
Finally, tell Laravel about the provider
The final thing we need to do is tell Laravel about the Service Provider. To do that we need to add to the providers
array in config/app.php
. Like so: App\Providers\FaceServiceProvider::class,
That’s it.
Conclusion
We now can see that the Service Container lets us define rules for how classes are auto-loaded during the dependency injection process. The Service Container code lives inside the Service Provider class, which must be registered in config/app.php
The Service Provider does more than just do this type of registration, but this is a good starting point.