Laravel service container must know

Time:2020-4-4

Laravel service container must know

The article was forwarded from the professional laravel developer community. Original link: https://learnku.com/laravel/t

To learn how to build an application with laravel is not only to learn how to use different classes and components in the framework, but also to remember allartisanCommand or all helper functions (we have Google). Learning to code with laravel is learning its philosophy and elegant and charming grammar. I personally think it’s an art and craft (coincidentally, laravel engineers are sometimes called web artists). This is also true for other frameworks.

Service containers and IOC containers are the main parts of laravel’s philosophy. As a laravel developer, it’s an important part for you to understand and use the service container correctly, because it’s the core of any laravel application.

Basics

Although the IOC container is essentially a common PHP class, I like to think of it as a “trick in the bag.”. This “bag” means that we place or “bind” any object service that we need to run in the laravel application, from interface implementation to directory path and so on. So it’s called “the trick in the bag.”

Now we have a single object (IOC container) that contains all binding object services, so in our code, it is easy to get or “parse” these object services from this single object at any time

How to handle binding

Now suppose we have a special function fooservice class.

<?php
namespace App\Services;
class FooService
{
    public function __construct()
    {
        ...
    }
    public function doSomething()
    {
        // Code for Something.
    }
}

If we want to call the dosomething method of the class, we might do this:

$fooService = new \App\Services\FooService();\
$fooService->doSomething();

It doesn’t seem to be a problem, but the trouble is the ‘new’ keyword here. I mean that although this is good, we can do it more elegantly (remember to write code in an elegant way like laravel).

How to bind?

Binding is so simple that it can be done in one line of code

$this->app->bind('FooService', \App\Services\FooService::class);

In laravel, we often say: “inject fooservice service into package cleverly”.

Of course, there are other ways to bind a service according to the usage scenario and service mode, as long as you understand its basic idea. For a complete reference to bindings, see laravel’s documentation for the service container

Note that the service must be bound to the service provider’s registration method.

How to parse?

After the service is bound to the container, we can get or parse the service anywhere in the application

//We can do this with IOC
$fooService = app()->make('FooService');
$fooService->doSomething();
//It can also be reduced to one line of code
app()->make('FooService')->doSomething();

We just need to tell laravel, “remember fooservice, give it to me when I need it.” have you noticed? Creating a service with IOC makes the code simpler, clearer and easier to read. This is the elegance of laravel, and it will make your code easier to test, Because when you test, you can replace fooservice with a fake class

Binding interface in container

In object-oriented programming, an interface is a way to create classes that must follow certain planning or constraints. This helps other developers create code that matches the constraints set in your interface. This forces them to pass legal arguments to functions and return specific data types, although their methods may be implemented differently. In this way, you can easily determine 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 specific interface. In this way, when we parse the interface, we will finally get the concrete class bound to it.

$this->app->bind(FooInterface::class, FooClass::class);

Therefore, whenFooInterfaceBeing parsed successfully, laravel is smart enough to give us oneFooClassExamples.

Now imagine that we’ve written aFooInterfaceThe better way to achieve this is calledBarClass, and we want to replace it withFooClassAll we need to do is:

$this->app->bind(FooInterface::class, BarClass::class);

Our code is still working because we know thatBarClassWill follow our interface, even ifBarClassWe can also switch back toFooClass。 This is a good way to upgrade your application code without too many regressions.

Dependency analysis

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 automatically resolve the dependencies of these services for us without writing a single line of code.

Imagine the following service classes in our project.

<?php
class BarService 
{
  /**
   *What to do.
   * 
   * @return string
   */
  public function somethingToDo()
  {
    return 'I am doing something';
  }
}
<?php
class FooService 
{
  /**
   *Barservice instance
   * 
   * @var BarService
   */
  protected $bar;
  
  /**
   *Create a new fooservice instance
   * 
   * @param BarService $bar
   */
  public function __construct(BarService $bar)
  {
    $this->bar = $bar;
  }
  
  /**
   *Do something useful
   * 
   * @return string
   */
  public function doSomething()
  {
    return $this->bar->somethingToDo();
  }
}

We can seeFooServiceNeed oneBarServiceExamples. How can we bind it to a container so that when laravel gives us aFooServiceIt will also give us aBarServiceExamples?

You may think that the solution might be as follows:

$this->app->bind('Foo', new FooService(new BarService));

Technically, this is possible, but we don’t need to. Laravel solves this problem automatically by using PHP’s powerful reflection feature. So you just need to bind as usual:

$this->app->bind('Foo', FooService::class);

Now, when the code resolves toFooWhen, laravel will look forFooServiceService, when it is found that it needs aBarServiceAn instance of the service; laravel will look for it againBarServiceService and provide the instantiated object toFooServiceThe constructor of the service to create a complete instance for us. These processes do not need us to write a line of code, it is really a very amazing and clear thinking!!

In addition, the above process will be provided to all dependencies. So, ifBarServiceServices also have their own dependencies, which will be solved in the above way.

Last words

There are many great things to discuss and learn about laravel’s service container. I hope this introduction can give you some inspiration and help you to deepen your understanding of containers.

I encourage you to learn more about [docs] by reading the documentation
( https://laravel.com/docs/5.6/… )。

Thank you for reading.

Recommended Today

PHP Basics – String Array Operations

In our daily work, we often need to deal with some strings or arrays. Today, we have time to sort them out String operation <?php //String truncation $str = ‘Hello World!’ Substr ($STR, 0,5); // return ‘hello’ //Chinese string truncation $STR = ‘Hello, Shenzhen’; $result = mb_ Substr ($STR, 0,2); // Hello //First occurrence of […]