What is a Service Container?
Service Container. It is a mechanism created by Laravel that facilitates the management of dependencies between classes. This subject is directly linked to Addiction Injection - Dependency Injection.
The Service Container aims to automate/facilitate the process of resolving dependencies between classes, since it stores the instance or the definition of how a given class should be instantiated. Thus, in each definition of a service, one has knowledge of the dependency that should be used for it.
Note: is not something exclusive of the term Laravel Service Container. I believe that the Symfony already adopted this idea before Laravel himself.
But what is an addiction?
First I want to explain this point: Dependency is in classes that depend on instances of others. This "dependency" is usually defined in the constructor or setters.
A basic example where A depends on B that depends on C:
class A {
protected $b;
public function __construct(B $b) {
$this->b = $b;
}
public function fazAlgumaCoisaComB()
{
$this->b->blah();
}
}
class B{
protected $c;
public function __construct(C $c) {
$this->c = $c;
}
}
In this small example, we see that to create the instance of A
, it is necessary to have a B
, which also depends on C
.
In the case of Service Container, you usually define a name for the service and assign it to an instance of the class (usually in Singleton cases) or tie its creation within an anonymous function.
For example:
$this->app->bind('C', function ($app) {
return new C;
});
$this->app->bind('B', function($app)
{
return new B($app[C::class]); // ou $app['C']
});
In the above case, when calling App::make('B')
or $app['B']
, you will be creating an instance of B
. But note that instead of having to define at all times what is the instance of C
which will be used in B
, the process was done automatically. That is, you did not need to keep repeating the process of setting the dependency C
.
When should I use this feature?
I believe that the best way to use it is when it would become laborious every time to use an object to have to instantiate it manually and go building the other dependencies.
For example, it would be more feasible for you to use an instance of C
in the first example below.
Example 1:
app('A')->fazAlgumaCoisaComB()
Example 2:
$a = new A(new B(new C));
$a->fazAgumaCoisaComB();
The above example is simple, but imagine in complex classes, whose instance is hard to get, if you were to do as in the second example!
In addition, with Laravel’s intelligent mechanism of automatically injecting dependencies through the Parameter Type, it becomes an even greater advantage to use the Service Container:
Example:
function getIndex(B $c, C $c) {
// As injeções serão feitas automaticamente por causa
// do service container registrado para eles
}
The example above reminds me a little of the Angularjs s2
Another advantage is that if you change any dependencies on any of your classes, you will need to change the code in one place. If you do it manually, you have to change all the places where you set the instance of the object that has the dependency.
What advantages it can bring to my web application?
When to this, I do not believe that the impact is something visible to the end user. This is something that will help the developer spend less time on repetitions and defining dependencies throughout a project.
I asked a similar question here on the site, which may help clarify some doubts:
What are the design standards for Serviceprovider and Servicecontainer used in Laravel and Symfony?
Important readings: