I was reading about Service Container in Laravel, but I was not able to fully understand the purpose of this feature.
I know that to create new services we have to use some Laravel methods:
App::bind()
or
App::instance()
there are others.
I was reading about Service Container in Laravel, but I was not able to fully understand the purpose of this feature.
I know that to create new services we have to use some Laravel methods:
App::bind()
or
App::instance()
there are others.
What is Service Container?
Service Container. It is a mechanism created by Laravel that facilitates the management of dependencies between classes. This subject is linked directly to Dependency Injection .
The Service Container is intended to automate / facilitate the process of resolving dependencies between classes, since it stores the instance or definition of how a particular class should be instantiated. Thus, in each definition of a service, one has the knowledge of the dependency that should be used for it.Note: is not something exclusive of Laravel the term Service Container . I think Symfony already adopted this idea before Laravel itself.
But what is a dependency?
First I want to explain this point: Dependency are in classes that depend on instances of others. This "dependency" is usually defined in the constructor or in setters.
A basic example where A depends on B which 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 an instance of B
, which also depends on C
.
In the case of the Service Container, you generally define a name for the service and assign it to an instance of the class (usually in Singleton cases), or tie it to an anonymous function.
For examples:
$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 you call App::make('B')
or $app['B']
, you are creating an instance of B
. But note that, instead of having to define at all times what the C
instance will be used in B
, the process was done automatically. That is, you did not have to keep repeating the process of setting the dependency of C
.
When should I use this feature?
I think the best way to use it is when it would become laborious every time you use an object you have to instantiate it manually and build other dependencies.
For example, it would be more feasible 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 laborious to get, if you were to do as in the second example!
In addition, with Laravel's intelligent mechanism for inject dependencies automatically 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 AngularJS s2
Another advantage is that if you change some dependency of some class of your, you will have to change the code in one place. If you do this manually, you will have to change all the places where you defined the instance of the object that has the dependency.
What advantages can it bring to my web application?
When that happens, I do not think the impact is something visible to the end user. This is something that will help the developer spend less time on repetitions and definition of dependencies throughout a project.
I asked a similar question here on the site, which might help clarify some doubts:
What are the ServiceProvider and ServiceContainer design patterns used in Laravel and Symfony?
Important readings: