Demystifying The Service Container

Demystifying The Service Container

At the Laravel Mumbai meetup - May, 2019.

A deep understanding of the service container is essential to building a powerful, large application, as well as for contributing to the Laravel core itself. In my talk, I will share my knowledge that will help the audience with the former part resulting in them achieving the later part.

2a7ba13d721266cad1d63b1d3fbc0118?s=128

Harish Toshniwal

May 25, 2019
Tweet

Transcript

  1. Demystifying The Container Also known as the IOC container, DI

    container & Service container @introwit 1
  2. "A deep understanding of the Laravel service container is essential

    to building a powerful, large application, as well as for contributing to the Laravel core itself." 1 Laravel documentation @introwit 2
  3. Container @introwit 3

  4. Storyline of this talk 4 Let's prepare some food !

    4 You enter the kitchen to see some spices are on the first shelf, some on second, etc " 4 Not enough funds to order from Uber Eats # Be the hero chef of your own story kitchen! @introwit 4
  5. The Problem Spices are scattered. Have to reach out to

    different places again & again to get the spices. Put them back after the food is prepared. Repeat. It's not really in your control. The control is with the spices we are dependent on to prepare the food. @introwit 5
  6. IOC Inversion Of Control You took all the spices and

    added them to a container with respective labels. Now you don't need to reach-out to or search at different places. You inverted the control. @introwit 6
  7. DI Dependency Injection Now the need for all the things

    you are dependent upon can be fulfilled by that container. The container will inject the dependency in the food as per your needs. @introwit 7
  8. "The Laravel service container is a powerful tool for managing

    class dependencies and performing dependency injection." 1 Laravel documentation @introwit 8
  9. MasterChef or a Laravel meet-up? @introwit 9

  10. app() @introwit 10

  11. But why isn't it called container()? Because the instances app()

    method generates are of the class called Application, and that class extends the Container class. @introwit 11
  12. So to create an instance of the container: $container =

    app(); @introwit 12
  13. Resolving & Binding @introwit 13

  14. Resolving things out of the container $car = app()->make(Car::class); vs

    $car = new Car; @introwit 14
  15. Resolving things out of the container $car = app()->make(Car::class); vs

    $car = new Car(Engine $engine); @introwit 15
  16. Resolving things out of the container $car = app()->make(Car::class); vs

    $car = new Car(Engine $engine(Oil $oil)); @introwit 16
  17. The magic called "Reflection" ! @introwit 17

  18. Reflection It's the ability of a programme to inspect &

    describe itself. Remember get_class($data) or get_class_methods(Car::class)? PS: There are many more PHP Reflection functions available. @introwit 18
  19. How Laravel Uses Reflection? app()->make(Car::class); -> Get the list of

    dependencies. (The class Car has a dependency called $engine) -> Use the typehint and instantiate the dependency and pass it. (Use the Engine typehint to reach the class) @introwit 19
  20. What if no typehints are available? :( We can manually

    bind things into the container. So that when a typehint is unavailable, our code doesn't break and fallbacks to check if we have defined some bindings for the same. @introwit 20
  21. Assume $engine wasn't typehinted. class Car { function __construct($engine) {}

    } app()->make(Car::class) would then fail since it wouldn't know what exactly $engine is? @introwit 21
  22. Binding things into the container app()->bind(Car::class, function () { return

    new Car(new Engine); }); Now when we do app()->make(Car::class) or whenever Car::class is resolved out of the container, it would run the callback above and return what we define. @introwit 22
  23. What else? @introwit 23

  24. Contextual Binding $this->app->when(PhotoController::class) ->needs(Filesystem::class) ->give(function () { return Storage::disk('local'); });

    $this->app->when([VideoController::class, UploadController::class]) ->needs(Filesystem::class) ->give(function () { return Storage::disk('s3'); }); @introwit 24
  25. Container Events $this->app->resolving(function ($object, $app) { // Called when container

    resolves object of any type... }); $this->app->resolving(Storage::class, function ($api, $app) { // Called when container resolves object of "Storage" class... // Useful for things like setting up some props or credentials/authentication with the object }); @introwit 25
  26. Few more container goodies 4 You can bind anything into

    the container, something as simple as a dynamic key-value pair: app()->bind('random-string', function ($app, $params) { return str_random($params['length']); }); // app()->makeWith('random-string', ['length' => 5]); 4 Easily Swap Implementations. @introwit 26
  27. @introwit @introwit 27