Slide 1

Slide 1 text

Entenda o Container do Laravel

Slide 2

Slide 2 text

Ravan Scafi Back-end Developer na Leroy Merlin Brasil Co-organizador do Meetup do Laravel SP Evangelista do PHPSP @ravanscafi

Slide 3

Slide 3 text

Service Container Gerencia as dependências de classes

Slide 4

Slide 4 text

Service Container Faz injeção de dependências

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

calculateProfit($sales); $htmlPresenter = new HtmlPresenter(); return $htmlPresenter->present($monthlyProfit); } }

Slide 9

Slide 9 text

calculateProfit($sales); $htmlPresenter = new HtmlPresenter(); return $htmlPresenter->present($monthlyProfit); } } ProfitReport Acoplado ao HtmlPresenter

Slide 10

Slide 10 text

public function getProfitReport($sales) { $report = new ProfitReport(); return $report->generateReport($sales); } Chamando o Report:

Slide 11

Slide 11 text

Controller Profit Generator Html Report depende de depende de

Slide 12

Slide 12 text

Problemas Maior interdepência

Slide 13

Slide 13 text

Problemas Manutenção mais difícil

Slide 14

Slide 14 text

Problemas Menor legibilidade do código

Slide 15

Slide 15 text

Como Resolver?

Slide 16

Slide 16 text

É necessário Desacoplar as Classes!

Slide 17

Slide 17 text

Como desacoplar?

Slide 18

Slide 18 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com um Setter

Slide 19

Slide 19 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com um Setter

Slide 20

Slide 20 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com um Setter

Slide 21

Slide 21 text

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:

Slide 22

Slide 22 text

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:

Slide 23

Slide 23 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com Injeção no Construtor

Slide 24

Slide 24 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } } Invertendo a dependência com Injeção no Construtor

Slide 25

Slide 25 text

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:

Slide 26

Slide 26 text

Legal, Mas... E o Container do Laravel? O que tem a ver?

Slide 27

Slide 27 text

Service Container Gerencia as dependências de classes

Slide 28

Slide 28 text

Service Container Faz injeção de dependências

Slide 29

Slide 29 text

Service Container Também conhecido como IoC Container (IoC = Inversion of Control)

Slide 30

Slide 30 text

Como?

Slide 31

Slide 31 text

Injeta Dependências no Construtor* Automagicamente! * e em outros lugares também

Slide 32

Slide 32 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } }

Slide 33

Slide 33 text

public function getProfitReport($sales) { $htmlPresenter = new Helpers\HtmlPresenter(); $report = new App\ProfitReport($htmlPresenter); return $report->generateReport($sales); } Antes:

Slide 34

Slide 34 text

public function getProfitReport($sales) { $report = app(App\ProfitReport::class); return $report->generateReport($sales); } Depois:

Slide 35

Slide 35 text

Como? Que bruxaria foi essa?

Slide 36

Slide 36 text

Bindings (ligações)

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Bind inválido / não criado

Slide 39

Slide 39 text

Bind de closures

Slide 40

Slide 40 text

Bind de classes

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

Ahh, a dependência do HtmlPresenter eu sei resolver!

Slide 45

Slide 45 text

Mágica!

Slide 46

Slide 46 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } }

Slide 47

Slide 47 text

É, não é tão mágico assim*!

Slide 48

Slide 48 text

Voltando ao nosso exemplo do Report

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Ambos deveriam depender de abstrações.

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

Detalhes devem depender de abstrações.

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Controller Profit Report Html Presenter depende de depende de Json Presenter Presenter Interface implementa implementa

Slide 57

Slide 57 text

Slide 58

Slide 58 text

Slide 59

Slide 59 text

Slide 60

Slide 60 text

presenter = $presenter; } public function generateReport($sales) { $monthlyProfit = $this->calculateProfit($sales); return $this->presenter->present($monthlyProfit); } }

Slide 61

Slide 61 text

Eita!

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Ahá, sucesso!

Slide 64

Slide 64 text

Service Providers Registram serviços no Framework!

Slide 65

Slide 65 text

app->bind(Helpers\PresenterInterface::class, function ($app) { return new Helpers\HtmlPresenter(); }); } }

Slide 66

Slide 66 text

'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

Slide 67

Slide 67 text

'default' => env('DB_CONNECTION', 'mysql'), config/database.php O que será que o framework faz por baixo dos panos?

Slide 68

Slide 68 text

Container: Instances

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

Container: Singleton

Slide 71

Slide 71 text

Facades Acesso “estático” para serviços

Slide 72

Slide 72 text

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

Legal, Mas... Agora tenho que fazer uma interface para cada classe do meu sistema?

Slide 75

Slide 75 text

NÃO! Utilize o conceito como um guia

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

Onde ir a Seguir

Slide 78

Slide 78 text

Documentação Laravel ● Service Container ● Service Providers ● Facades ● Contracts PSR 11 - Container interface

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

Obrigado! @ravanscafi

Slide 82

Slide 82 text

Estamos Contratando! Dev BackEnd, Dev FrontEnd, UX [email protected]

Slide 83

Slide 83 text

Agradecimentos Agradecimentos especiais a todos do SlidesCarnival que fizeram e disponibilizaram o template da apresentação gratuitamente.