Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Entenda de uma vez por todas o Container do Laravel

Db982994346dad910547a7c62a90dadd?s=47 Ravan Scafi
November 17, 2017

Entenda de uma vez por todas o Container do Laravel

Mais do que uma forma de injetar dependências no construtor de classes, o container do Laravel é uma ferramenta poderosa do framework, que você já usa e talvez não conheça. Entenda como o Container auxilia no Dependency Inversion Principle do SOLID, conheça os principais tipos de bindings e, de quebra, aprenda sobre Contracts, Service Providers e Facades.

Db982994346dad910547a7c62a90dadd?s=128

Ravan Scafi

November 17, 2017
Tweet

More Decks by Ravan Scafi

Other Decks in Programming

Transcript

  1. Entenda o Container do Laravel

  2. Ravan Scafi Back-end Developer na Leroy Merlin Brasil Co-organizador do

    Meetup do Laravel SP Evangelista do PHPSP @ravanscafi
  3. Service Container Gerencia as dependências de classes

  4. Service Container Faz injeção de dependências

  5. Mas... O que é uma dependência?

  6. Dependência Quão conectado um “módulo” está a outro

  7. Acoplamento Indica um grau de dependência entre módulos

  8. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { public function

    generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); $htmlPresenter = new HtmlPresenter(); return $htmlPresenter->present($monthlyProfit); } }
  9. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { public function

    generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); $htmlPresenter = new HtmlPresenter(); return $htmlPresenter->present($monthlyProfit); } } ProfitReport Acoplado ao HtmlPresenter
  10. public function getProfitReport($sales) { $report = new ProfitReport(); return $report->generateReport($sales);

    } Chamando o Report:
  11. Controller Profit Generator Html Report depende de depende de

  12. Problemas Maior interdepência

  13. Problemas Manutenção mais difícil

  14. Problemas Menor legibilidade do código

  15. Como Resolver?

  16. É necessário Desacoplar as Classes!

  17. Como desacoplar?

  18. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { private $presenter;

    public function setPresenter(HtmlPresenter $presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com um Setter
  19. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { private $presenter;

    public function setPresenter(HtmlPresenter $presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com um Setter
  20. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { private $presenter;

    public function setPresenter(HtmlPresenter $presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com um Setter
  21. public function getProfitReport($sales) { $report = new App\ProfitReport(); $htmlPresenter =

    new Helpers\HtmlPresenter(); $report->setPresenter($htmlPresenter); return $report->generateReport($sales); } Utilizando o Report com o Setter:
  22. public function getProfitReport($sales) { $report = new App\ProfitReport(); $htmlPresenter =

    new Helpers\HtmlPresenter(); $report->setPresenter($htmlPresenter); return $report->generateReport($sales); } Utilizando o Report com o Setter:
  23. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { private $presenter;

    public function __construct(HtmlPresenter $presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com Injeção no Construtor
  24. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { private $presenter;

    public function __construct(HtmlPresenter $presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com Injeção no Construtor
  25. public function getProfitReport($sales) { $htmlPresenter = new Helpers\HtmlPresenter(); $report =

    new App\ProfitReport($htmlPresenter); return $report->generateReport($sales); } Utilizando o Report com Injeção no Construtor:
  26. Legal, Mas... E o Container do Laravel? O que tem

    a ver?
  27. Service Container Gerencia as dependências de classes

  28. Service Container Faz injeção de dependências

  29. Service Container Também conhecido como IoC Container (IoC = Inversion

    of Control)
  30. Como?

  31. Injeta Dependências no Construtor* Automagicamente! * e em outros lugares

    também
  32. <?php namespace App; use Helpers\HtmlPresenter; class ProfitReport { private $presenter;

    public function __construct(HtmlPresenter $presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } }
  33. public function getProfitReport($sales) { $htmlPresenter = new Helpers\HtmlPresenter(); $report =

    new App\ProfitReport($htmlPresenter); return $report->generateReport($sales); } Antes:
  34. public function getProfitReport($sales) { $report = app(App\ProfitReport::class); return $report->generateReport($sales); }

    Depois:
  35. Como? Que bruxaria foi essa?

  36. Bindings (ligações)

  37. Resolução automática (similar ao new)

  38. Bind inválido / não criado

  39. Bind de closures

  40. Bind de classes

  41. Mas e esse cara, que tem uma dependência no construtor?

  42. None
  43. None
  44. Ahh, a dependência do HtmlPresenter eu sei resolver!

  45. Mágica!

  46. <?php namespace App; class ProfitReport { private $presenter; public function

    __construct($presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } }
  47. É, não é tão mágico assim*!

  48. Voltando ao nosso exemplo do Report

  49. E se agora eu quisesse apresentar o relatório em JSON?

  50. Dependency Inversion Principle (S.O.L.I.D.)

  51. Módulos de alto nível não deveriam depender de módulos de

    baixo nível.
  52. Ambos deveriam depender de abstrações.

  53. Abstrações não deveriam depender de detalhes.

  54. Detalhes devem depender de abstrações.

  55. “ "Programe para uma interface, não uma implementação." Gang of

    Four, 1995
  56. Controller Profit Report Html Presenter depende de depende de Json

    Presenter Presenter Interface implementa implementa
  57. <?php namespace Helpers; interface PresenterInterface { public function present($data); }

  58. <?php namespace Helpers; class HtmlPresenter implements PresenterInterface { public function

    present($data) { return view('reports', compact('data')); } }
  59. <?php namespace Helpers; class JsonPresenter implements PresenterInterface { public function

    present($data) { return json_encode(compact('data')); } }
  60. <?php namespace App; use Helpers\PresenterInterface; class ProfitReport { private $presenter;

    public function __construct(PresenterInterface $presenter) { $this->presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } }
  61. Eita!

  62. Ué? (o container aceita qualquer string como “chave”)

  63. Ahá, sucesso!

  64. Service Providers Registram serviços no Framework!

  65. <?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class PresenterServiceProvider extends ServiceProvider {

    public function register() { $this->app->bind(Helpers\PresenterInterface::class, function ($app) { return new Helpers\HtmlPresenter(); }); } }
  66. 'providers' => [ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class,

    Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, // ... config/app.php
  67. 'default' => env('DB_CONNECTION', 'mysql'), config/database.php O que será que o

    framework faz por baixo dos panos?
  68. Container: Instances

  69. <?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class PresenterServiceProvider extends ServiceProvider {

    public function register() { $this->app->singleton(Helpers\PresenterInterface::class, function ($app) { var_dump('fui chamado!'); return new Helpers\HtmlPresenter(); }); } } Container: Singleton
  70. Container: Singleton

  71. Facades Acesso “estático” para serviços

  72. <?php namespace Illuminate\Support\Facades; class Cache extends Facade { protected static

    function getFacadeAccessor() { return 'cache'; } } Cache Facade
  73. None
  74. Legal, Mas... Agora tenho que fazer uma interface para cada

    classe do meu sistema?
  75. NÃO! Utilize o conceito como um guia

  76. NÃO! Use inversão de dependências, mesmo com classes concretas!

  77. Onde ir a Seguir

  78. Documentação Laravel • Service Container • Service Providers • Facades

    • Contracts PSR 11 - Container interface
  79. None
  80. None
  81. Obrigado! @ravanscafi

  82. Estamos Contratando! Dev BackEnd, Dev FrontEnd, UX rscafi@leroymerlin.com.br

  83. Agradecimentos Agradecimentos especiais a todos do SlidesCarnival que fizeram e

    disponibilizaram o template da apresentação gratuitamente.