This is a community collaborative translation of the article, has been translated, more information please click
Introduction to collaborative translation 。
artisan
The service container and the IOC container are a major part of Laravel’s philosophy. As a Laravel developer, understanding and using the service container properly is an important part of your mastery of it, as it is at the heart of any Laravel application.
basis
While the IOC container is essentially just a normal PHP class, I like to think of it as a “trick in a bag.” This “bag” is where we place or “bind” any object services we need to run in the Laravel application, from interface implementations to directory paths and so on. So it’s called “Trick in the bag”
We now have a single object (IOC container) that contains all the bound object services, so it is easy to retrieve or “parse” these object services from this single object at any time in our code
How the binding is handled
Now suppose we have a special FooService class.
<? php namespace App\Services; class FooService { public function __construct() { ... } public function doSomething() { // Code for Something. } }Copy the code
If we were to call the class’s doSomething method, we might doSomething like this:
$fooService = new \App\Services\FooService(); \ $fooService->doSomething();Copy the code
This doesn’t seem to be a problem, but the trouble is the ‘new’ keyword here. I mean, while that’s fine, we can do it more elegantly (remember to write code like Laravel, elegantly).
How to bind?
Binding is simple enough to be done in a single line of code
$this->app->bind('FooService', \App\Services\FooService::class);Copy the code
In Laravel we often say, “Inject the FooService service smartly into the package.”
Service container
It is important to note that the service must be bound to the service provider’s registration method.
How to parse?
Once a service is bound to a container, it can be retrieved or resolved anywhere in the application.
$fooService = app()->make(' fooService '); $fooService->doSomething(); App ()->make('FooService')->doSomething();Copy the code
We just have to tell Laravel, “Remember FooService and give it to me when I need it.” Did you notice that? Creating services with IoC makes code simpler, cleaner, and easier to read. This is the beauty of Laravel and will make your code easier to test, since you can replace FooService with a forged class when you test (I think you’re familiar with how to forge classes in tests).
Bind interfaces in containers
In object-oriented programming, an interface is a way to create classes that must follow some kind of plan or constraint. This helps other developers create code that matches the constraints set in your interface. This forces them to pass legitimate arguments to the function and return a specific data type, although the implementation of their methods may differ. In this way, you can easily be sure that different implementations that inherit the same interface will work in the same way.
In Laravel’s container we can bind the implementation of a particular interface, and that way, when we parse the interface, we end up with a concrete class bound to it.
$this->app->bind(FooInterface::class, FooClass::class);Copy the code
FooInterface
FooClass
FooInterface
BarClass
FooClass
$this->app->bind(FooInterface::class, BarClass::class);Copy the code
Our code still works because we know that BarClass will follow our interface, and even if BarClass doesn’t behave as expected we can switch back to FooClass. This was a good way to update your application’s code without too many regressions.
Depend on the resolution
We know that Laravel can parse the services and interfaces we bind in the container, but it can do more than that. In fact, it can resolve the dependencies of these services automatically for us without us having to write a line of code.
Imagine our project with the following service classes.
<? PHP class BarService {/** * what to do. * * @return string */ public function somethingToDo() { return 'I am doing something'; }}Copy the code
<? PHP class FooService {/** * BarService instance ** @var BarService */ protected $bar; Public function __construct(BarService $bar) {$this->bar = $bar; $this->bar = $bar; Public function doSomething() {return $this->bar->somethingToDo(); }}Copy the code
FooService
BarService
FooService
BarService
You might think that the solution might look something like this:
$this->app->bind('Foo', new FooService(new BarService));Copy the code
View the other version
Technically, this is possible, but we don’t need to do it. Laravel automatically solves this problem for us by using the powerful reflection features of PHP. Therefore, you just need to bind as usual:
$this->app->bind('Foo', FooService::class);Copy the code
Foo
FooService
BarService
BarService
FooService
In addition, the above procedures will be provided for all dependencies. So, if the BarService service has its own dependencies, it will be resolved in the same way.
The last word
There are many great things to discuss and learn about Laravel’s service container. I hope this brief introduction has given you some inspiration and helped you deepen your understanding of containers.
Laravel-china.org/docs/larave…
Thank you for reading.
Original address:
M. otdev. Co/understandi…Translation Address:
Laravel-china.org/topics/1027…
All translations in this article are for study and communication purposes only. Please note the translator, source, and link to this article
Our translation work is in accordance with
CCIf our work has violated your rights and interests, please contact us immediately.