Laravel's Dependency Injection Container in Depth

Posted on: July 22, 2020 04:29 PM

Posted by: Renato

Categories: Laravel PHP

Views: 36

Recipiente de injeção de dependência do Laravel em profundidade

Laravel’s Dependency Injection Container in Depth

[Laravel] (https://laravel.com/) possui um poderoso contêiner de Inversão de controle (IoC) / Injeção de dependência (DI). Infelizmente, a [documentação oficial] (https://laravel.com/docs/6.x/container) não cobre todas as funcionalidades disponíveis, por isso decidi experimentar e documentar por mim mesmo. O seguinte é baseado no [Laravel 5.4.26] (https://github.com/laravel/framework/tree/6.x/src/Illuminate/Container) - outras versões podem variar.

Introdução à injeção de dependência

Não tentarei explicar os princípios por trás do DI / IoC aqui - se você não estiver familiarizado com eles, poderá ler [O que é injeção de dependência?] (Http://fabien.potencier.org/what-is- dependência-injeção.html) por Fabien Potencier (criador da estrutura [Symfony] (http://symfony.com/)).

Acessando o Container

Existem várias maneiras de acessar a instância do Container * no Laravel, mas a mais simples é chamar o método auxiliar app ():

  1. $ container = app ();

Não vou descrever as outras maneiras hoje - em vez disso, quero me concentrar na própria classe Container.

Nota: Se você ler os [documentos oficiais] (https://laravel.com/docs/6.x/container), ele usará $ this-> app em vez de$ container.

(* Nos aplicativos Laravel, na verdade, é uma subclasse de Container chamada [Application] (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Foundation/Application.php) (é por isso que o assistente é chamado app ()), mas para este post vou descrever apenas os métodos [Container] (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Container/Container.php).)

Usando Illuminate \ Container Outside Laravel

Para usar o Container fora do Laravel, [instale-o] (https://packagist.org/packages/illuminate/container) e depois:

  1. use Illuminate \ Container \ Container;
  2. $ container = Container :: getInstance ();

Uso básico

O uso mais simples é digitar o construtor da sua classe com as classes que você deseja injetar:

  1. classe MyClass
  2. {
  3. private $ dependency;
  4. função pública __construct (AnotherClass $ dependency)
  5. {
  6. $ this-> dependency = $ dependency;
  7. }
  8. }

Em vez de usar new MyClass, use o métodomake ()do Container:

  1. $ instance = $ container-> make (MyClass :: class);

O contêiner instanciará automaticamente as dependências, portanto isso é funcionalmente equivalente a:

  1. $ instance = new MyClass (new AnotherClass ());

(Exceto que AnotherClass poderia ter algumas dependências próprias - nesse caso, o Container as instanciaria recursivamente até que não houvesse mais.)

Exemplo prático

Aqui está um exemplo mais prático com base nos [PHP-DI docs] (http://php-di.org/doc/getting-started.html) - separando a funcionalidade de correspondência do registro do usuário:

  1. class Mailer
  2. {
  3. função pública mail ($ destinatário, $ content)
  4. {
  5. // Envia um email para o destinatário
  6. // ...
  7. }
  8. }
  1. class UserManager
  2. {
  3. private $ mailer;
  4. função pública __construct (Mailer $ mailer)
  5. {
  6. $ this-> mailer = $ mailer;
  7. }
  8. registro de função pública ($ email, $ password)
  9. {
  10. // Crie a conta do usuário
  11. // ...
  12. // Envie um email ao usuário para dizer olá!
  13. $ this-> mailer-> mail ($ email, 'Olá e bem-vindo!');
  14. }
  15. }
  1. use Illuminate \ Container \ Container;
  2. $ container = Container :: getInstance ();
  3. $ userManager = $ container-> make (UserManager :: class);
  4. $ userManager-> register ('[email protected] ',' MySuperSecurePassword! ');

Vinculando interfaces a implementações

O Container facilita a codificação para uma interface e instancia uma instância concreta em tempo de execução. Primeiro defina as interfaces:

  1. interface MyInterface {/ * ... * /}
  2. interface AnotherInterface {/ * ... * /}

E declare as classes concretas que implementam essas interfaces. Eles podem depender de outras interfaces (ou classes concretas como antes):

  1. class MyClass implementa MyInterface
  2. {
  3. private $ dependency;
  4. função pública __construct (AnotherInterface $ dependency)
  5. {
  6. $ this-> dependency = $ dependency;
  7. }
  8. }

Use bind () para mapear cada interface para uma classe concreta:

  1. $ container-> bind (MyInterface :: class, MyClass :: class);
  2. $ container-> bind (OutraInterface :: classe, OutraClasse :: classe);

Por fim, passe o nome da interface em vez do nome da classe para make ():

  1. $ instance = $ container-> make (MyInterface :: class);

Nota: Se você esquecer de vincular uma interface, receberá um erro fatal um pouco enigmático:

  1. Erro fatal: Unchaught ReflectionException: a classe MyInterface não existe`

Isso ocorre porque o contêiner tentará para instanciar a interface (new MyInterface), que não é uma classe válida.

Exemplo prático

Aqui está um exemplo prático disso - uma camada de cache permutável:

  1. interface Cache
  2. {
  3. public function get ($ key);
  4. função pública put ($ key, $ value);
  5. }
  1. class RedisCache implementa Cache
  2. {
  3. função pública get ($ key) {/ * ... * /}
  4. função pública put ($ key, $ value) {/ * ... * /}
  5. }
  1. class Worker
  2. {
  3. private $ cache;
  4. função pública __construct (Cache $ cache)
  5. {
  6. $ this-> cache = $ cache;
  7. }
  8. public function result ()
  9. {
  10. // Use o cache para algo ...
  11. $ result = $ this-> cache-> get ('worker');
  12. if ($ result === null) {
  13. $ result = do_something_slow ();
  14. $ this-> cache-> put ('trabalhador', $ resultado);
  15. }
  16. retornar $ resultado;
  17. }
  18. }
  1. use Illuminate \ Container \ Container;
  2. $ container = Container :: getInstance ();
  3. $ container-> bind (Cache :: classe, RedisCache :: classe);
  4. $ result = $ container-> make (Worker :: class) -> resultado ();

Vinculação de classes abstratas e concretas

A
associação também pode ser usada com classes abstratas:

```php $ container-> bind (MyAbstract :: class, MyConcreteClass :: class);

  1. Ou para substituir uma classe concreta por uma subclasse:
  2. ```php
  3. $ container-> bind (MySQLDatabase :: class, CustomMySQLDatabase :: class);

Ligações personalizadas

Se a classe exigir configuração adicional, você pode passar um fechamento em vez de um nome de classe como o segundo parâmetro para bind ():

  1. $ container-> bind (Database :: class, function (Container $ container) {
  2. return novo MySQLDatabase (MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASS);
  3. });

Sempre que a interface do banco de dados for necessária, uma nova instância do MySQLDatabase será criada e usada, com os valores de configuração especificados. (Para compartilhar uma única instância, consulte Singletons abaixo.) O fechamento recebe a instância Container como o primeiro parâmetro e pode ser usado para instanciar outras classes, se necessário:

  1. $ container-> bind (Logger :: class, function (Container $ container) {
  2. $ sistema de arquivos = $ container-> make (Sistema de arquivos :: classe);
  3. retornar novo FileLogger ($ filesystem, 'logs / error.log');
  4. });

Um fechamento também pode ser usado para personalizar como uma classe concreta é instanciada:

  1. $ container-> bind (GitHub \ Client :: class, function (Container $ container) {
  2. $ client = new GitHub \ Client;
  3. $ client-> setEnterpriseUrl (GITHUB_HOST);
  4. retorna $ client;
  5. });

Resolvendo

retornos de chamada Em vez de substituir completamente a ligação, você pode usar resolving () para registrar um retorno de chamada chamado depois que a ligação é revolvida:

  1. $ container-> resolving (GitHub \ Client :: classe, função ($ client, Container $ container) {
  2. $ client-> setEnterpriseUrl (GITHUB_HOST);
  3. });

Se houver vários retornos de chamada, todos eles serão chamados. Eles também trabalham para interfaces e classes abstratas:

  1. $ container-> resolving (Logger :: class, function (Logger $ logger) {
  2. $ logger-> setLevel ('debug');
  3. });
  4. $ container-> resolving (FileLogger :: classe, função (FileLogger $ logger) {
  5. $ logger-> setFilename ('logs / debug.log');
  6. });
  7. $ container-> bind (Logger :: classe, FileLogger :: classe);
  8. $ logger = $ container-> make (Logger :: classe);

Também é possível adicionar um retorno de chamada que sempre é chamado, não importa qual classe seja resolvida - mas acho que provavelmente é útil apenas para registrar / depurar:

  1. $ container-> resolving (function ($ objeto, Container $ container) {
  2. // ...
  3. });

Estendendo uma classe

Como alternativa, você também pode usar extend () para quebrar uma classe e retornar um objeto diferente:

  1. $ container-> extend (APIClient :: class, function ($ client, Container $ container) {
  2. retorna novo APIClientDecorator ($ client);
  3. });

O objeto resultante ainda deve implementar a mesma interface, caso contrário, você receberá um erro ao usar a dica de tipo.

Singletons

Com a ligação automática e o bind (), uma nova instância será criada (ou o fechamento será chamado) toda vez que for necessário. Para compartilhar uma única instância, use singleton () em vez de bind ():

  1. $ container-> singleton (Cache :: class, RedisCache :: class);

Ou com um fechamento:

  1. $ container-> singleton (Database :: class, function (Container $ container) {
  2. retorna novo MySQLDatabase ('localhost', 'testdb', 'user', 'pass') ;
  3. });

Para tornar uma classe concreta um singleton, passe essa classe sem o segundo parâmetro:

  1. $ container-> singleton (MySQLDatabase :: class);

Em cada caso, o objeto singleton será criado na primeira vez que for necessário e, em seguida, reutilizado a cada vez subseqüente. Se você já possui uma instância que deseja reutilizar, use o método instance (). Por exemplo, o Laravel usa isso para garantir que a instância Singleton Container seja retornada sempre que for injetada em uma classe:

  1. $ container-> instance (Container :: class, $ container);

# Nomes de ligação arbitrária

Você pode usar qualquer sequência arbitrária em vez de um nome de classe / interface - embora não seja possível usar dicas de tipo para recuperá-la e precisará usarmake ():

  1. $ container-> bind ('banco de dados', MySQLDatabase :: class);
  2. $ db = $ container-> make ('banco de dados');

Para suportar simultaneamente uma classe / interface e um nome abreviado, use alias ():

  1. $ container-> singleton (Cache :: class, RedisCache :: class);
  2. $ container-> alias (Cache :: classe, 'cache');
  3. $ cache1 = $ container-> make (Cache :: class);
  4. $ cache2 = $ container-> make ('cache');
  5. assert ($ cache1 === $ cache2);

Armazenando valores arbitrários

Você também pode usar o contêiner para armazenar valores arbitrários - por exemplo, dados de configuração:

  1. $ container-> instance ('database.name', 'testdb');
  2. $ db_name = $ container-> make ('nome do banco de dados');

Ele suporta a sintaxe de acesso ao array, o que torna isso mais natural:

  1. $ container ['
  2. $ db_name = $ container ['database.name'];

Quando combinado com as ligações de fechamento, você pode ver por que isso pode ser útil:

  1. $ container-> singleton ('database', function (Container $ container) {
  2. return new MySQLDatabase (
  3. $ container ['database.host' ],
  4. $ container ['database.name'],
  5. $ container ['database.user'],
  6. $ container ['database.pass']
  7. );
  8. });

(O próprio Laravel não usa o contêiner para configuração - ele usa uma classe [Config] separada (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Config/Repository.php) em vez disso - mas [PHP-DI] (http://php-di.org/doc/php-definitions.html#values) faz.)

Dica: A sintaxe da matriz também pode ser usada em vez de make () ao instanciar objetos:

  1. $ db = $ container ['database'];

Injeção de Dependência para Funções e Métodos

Até agora, vimos DI para construtores, mas o Laravel também suporta DI para funções arbitrárias:

  1. function do_something (Cache $ cache) {/ * ... * /}
  2. $ result = $ container-> call ('do_something');

Parâmetros adicionais podem ser passados ​​como uma matriz ordenada ou associativa:

  1. função php show_product (Cache $ cache, $ id, $ tab = 'details') {/ * ... * /}
  2. // show_product ($ cache, 1)
  3. $ container-> call ('show_product', [1]);
  4. $ container-> call ('show_product',
  5. // show_product ($ cache, 1, 'spec')
  6. $ container-> call ('show_product', [1, 'spec']);
  7. $ container-> call ('show_product', ['id' => 1, 'tab' => 'especificação']);

Isso pode ser usado para qualquer método que possa ser chamado:

Closures`

  1. $ encerramento = function (Cache $ cache) {/ * ... * /};
  2. $ container-> call ($ fechamento);

Métodos estáticos

  1. classe php SomeClass
  2. {
  3. função estática pública staticMethod (Cache $ cache) {/ * ... * /}
  4. }
  1. $ container-> call ([' SomeClass ',' staticMethod ']);
  2. // ou:
  3. $ container-> call ('SomeClass :: staticMethod' );

Métodos de instância

  1. class PostController
  2. {
  3. índice de função pública (Cache $ cache) {/ * ... * /}
  4. função pública show (Cache $ cache, $ id) {/ * ... * /}
  5. }
  1. $ controller = $ container-> make (PostController :: class);
  2. $ container-> call ([$ controller, 'index']);
  3. $ container-> call ([$ controller, 'show'], ['id' => 1]);

Atalho para chamar métodos de instância

Existe um atalho para instanciar uma classe e chamar um método de uma só vez - use a sintaxe ClassName @ methodName:

  1. $ container-> call ('PostController @ index ');
  2. $ container-> call ('PostController @ show', ['id' => 4]);

O contêiner é usado para instanciar a classe. Isso significa:

  1. Dependências são injetadas no construtor (assim como no método).
  2. Você pode definir a classe como um singleton se desejar que ela seja reutilizada.
  3. Você pode usar uma interface ou nome arbitrário em vez de uma classe concreta.

Por exemplo, isso funcionará:

  1. class PostController
  2. {
  3. public function __construct (Request $ request) {/ * ... * /}
  4. índice da função pública (Cache $ cache) {/ * ... * /}
  5. }
  1. $ container-> singleton ('post', PostController :: class);
  2. $ container-> call ('post @ index');

Finalmente, você pode passar um “método padrão” como o terceiro parâmetro. Se o primeiro parâmetro for um nome de classe sem método especificado, o método padrão será chamado. O Laravel usa isso para implementar [manipuladores de eventos] (https://laravel.com/docs/6.x/events#registering-events-and-listeners):

  1. $ container-> call (MyEventHandler :: class, $ parameters , 'lidar com');
  2. // Equivalente a:
  3. $ container-> call ('MyEventHandler @ handle', $ parameters);

 

Ligações de chamada de método O métodobindMethod ()pode ser usado para substituir uma chamada de método, por exemplo, para passar parâmetros adicionais:

  1. $ container-> bindMethod ('PostController @ index', function ($ controller, $ container) {
  2. $ posts = get_posts (...);
  3. retornar $ controller-> index ($ posts);
  4. });

Tudo isso funcionará, chamando o fechamento em vez do método original:

  1. $ container-> call ('PostController @ index');
  2. $ container-> call ('PostController', [], 'index');
  3. $ container-> call ([novo PostController, 'index']);

No entanto, quaisquer parâmetros adicionais para call () não são passados ​​para o fechamento e, portanto, não podem ser usados.

  1. $ container-> call ('PostController @ index', ['Não utilizado :-(']);

Notas: Este método não faz parte da [Interface do contêiner] (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Contracts/Container/Container.php), apenas o concreta [classe Container] (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Container/Container.php). Consulte [o PR onde foi adicionado] (https://github.com/laravel/framework/pull/16800) para
saber por que os parâmetros são ignorados.

Ligações contextuais

Às vezes, você deseja usar implementações diferentes de uma interface em lugares diferentes . Aqui está um exemplo adaptado do [Laravel docs] (https://laravel.com/docs/5.4/container#contextual-binding):

  1. $ container
  2. -> when (PhotoController :: class)
  3. -> needs ( Sistema de arquivos :: classe)
  4. -> give (LocalFilesystem :: class);
  5. $ container
  6. -> when (VideoController :: class)
  7. -> needs (Sistema de arquivos :: class)
  8. -> give (S3Filesystem :: class);

Agora o PhotoController e o VideoController podem depender da interface do sistema de arquivos, mas cada um receberá uma implementação diferente. Você também pode usar um fechamento para give (), assim como você pode com bind ():

  1. $ container
  2. -> when (VideoController :: class)
  3. -> needs (Filesystem :: class)
  4. -> give (function () {
  5. return Storage :: disk ('s3');
  6. });

Ou uma dependência nomeada:

  1. $ container-> instance ('s3', $ s3Filesystem);
  2. $ container
  3. -> when (VideoController :: class)
  4. -> needs (Sistema de arquivos :: classe)
  5. -> give ('s3');

Vinculando parâmetros a primitivas

Você também pode vincular primitivas (strings, inteiros, etc.) passando um nome de variável paraneeds ()(em vez de uma interface) e passando o valor paragive () :

  1. $ container
  2. -> when (MySQLDatabase :: class)
  3. -> needs ('$ username')
  4. -> give (DB_USER);

Você pode usar um fechamento para atrasar a recuperação do valor até que seja necessário:

  1. $ container
  2. -> when (MySQLDatabase :: class)
  3. -> needs ('$ username')
  4. -> give (function () {
  5. retornar config ('database.user');
  6. });

Aqui você não pode passar uma classe ou uma dependência nomeada (por exemplo, give ('database.user')) porque seria retornada como um valor literal - para fazer isso, seria necessário usar um fechamento:

  1. $ container
  2. -> when (MySQLDatabase :: class)
  3. -> needs ('$ username')
  4. -> give (function (Container $ container) {
  5. return $ container ['database.user'];
  6. });

Tagging

Você pode usar o contêiner para” marcar “ligações relacionadas:

  1. $ container-> tag (MyPlugin :: class, 'plugin');
  2. $ container-> tag (AnotherPlugin :: class, 'plugin');

E então recupere todas as instâncias marcadas como uma matriz:

  1. foreach ($ container-> tagged ('plugin') como $ plugin) {
  2. $ plugin-> init ();
  3. }

Ambos os parâmetrostag ()também aceitam matrizes:

  1. $ container-> tag ([MyPlugin :: class, AnotherPlugin :: class], 'plugin');
  2. $ container-> tag (MyPlugin :: class, ['plugin', 'plugin.admin']);

Rebinding

Nota: Isso é um pouco mais avançado e raramente é necessário - fique à vontade para ignorá-lo!

Um retorno de chamada rebinding () é chamado quando uma ligação ou instância é alterada após ele já foi usado - por exemplo, aqui a classe da sessão é substituída após ter sido usada pela classe Auth, portanto, a classe Auth precisa ser informada da alteração:

  1. $ container-> singleton (Auth :: classe, função (Container $ container) {
  2. $ auth = new Auth;
  3. $ auth-> setSession ($ container-> make (Session :: class));
  4. $ container-> rebinding (Session :: classe, função ($ container, $ session) use ($ auth) {
  5. $ auth-> setSession ($ session);
  6. });
  7. retorne $ auth;
  8. });
  9. $ container-> instance (Session :: class, new Session (['nome de usuário' => 'dave']));
  10. $ auth = $ container-> make (Auth :: class);
  11. echo $ auth-> nome de usuário (); // dave
  12. $ container-> instance (Session :: class, new Session (['nome de usuário' => 'danny']));
  13. echo $ auth-> nome de usuário (); // danny

(Para obter mais informações sobre religação, consulte [aqui] (https://stackoverflow.com/questions/38974593/laravels-ioc-container-rebinding-abstract-types) e [aqui] (https://code.tutsplus.com / tutorials / digging-to-laravels-ioc-container - cms-22167).)

refresh ()

Há também um método de atalho, refresh (), para lidar com esse padrão comum:

  1. $ container-> singleton (Auth :: classe, função (Container $ container) {
  2. $ auth = new Auth;
  3. $ auth-> setSession ($ container-> make (Session :: class));
  4. $ container-> refresh ( Session :: classe, $ auth, 'setSession');
  5. retorna $ auth;
  6. });

Ele também retorna a instância ou ligação existente (se houver), para que você possa fazer isso:

  1. // Isso funciona apenas se você chamar singleton () ou bind () na classe
  2. $ container-> singleton (Session :: class);
  3. $ container-> singleton (Auth :: classe, função (Container $ container) {
  4. $ auth = new Auth;
  5. $ auth-> setSession ($ container-> refresh (Sessão :: classe, $ auth, 'setSession'));
  6. retornar $ auth;
  7. });

(Pessoalmente, acho essa sintaxe mais confusa e prefiro a versão mais detalhada acima!)

Nota: Esses métodos não fazem parte da [Interface do contêiner] (https://github.com/laravel/framework /blob/5.4/src/Illuminate/Contracts/Container/Container.php), apenas a [classe Container] concreta (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Container/Container.php) .

Substituindo Parâmetros do Construtor

O método makeWith () permite que você passe parâmetros adicionais para o construtor. Ele ignora quaisquer instâncias ou singletons existentes e pode ser útil para criar várias instâncias de uma classe com parâmetros diferentes enquanto ainda injeta dependências:

  1. class Post
  2. {
  3. public function __construct (Database $ db, int $ id) {/ *. .. * /}
  4. }
  1. $ post1 = $ container-> makeWith (Post :: class, ['id' => 1]);
  2. $ post2 = $ container-> makeWith (Post :: class, ['id' => 2]);

Nota: No Laravel 5.3 e abaixo, era simplesmente make ($ class, $ parameters). Foi [removido no Laravel 5.4] (https://github.com/laravel/internals/issues/391), mas depois [adicionado novamente como makeWith ()] (https://github.com/laravel/framework/ pull / 18271) em 5.4.16 . No Laravel 5.5, parece que ele será [revertido para a sintaxe do Laravel 5.3] (https://github.com/laravel/framework/pull/19201) .

Outros métodos

Que abrange todos os métodos que eu acho que são útil - mas, para finalizar, aqui está um resumo dos métodos públicos restantes …

bound ()

O método bound () retorna true se a classe ou o nome tiver sido associado com bind ()singleton ()instance () ou alias ().

  1. if (! $ container-> bound ('database.user')) {
  2. // ...
  3. }

Você também pode usar a sintaxe de acesso a matriz eisset ():

  1. if (isset ($ recipiente [ 'database.user'])!) {
  2. // ...
  3. }

Pode ser redefinido com unset (), que remove a ligação / instance / alias especificada.

  1. unset ($ container ['database.user']);
  2. var_dump ($ container-> bound ('database.user')); // false

bindIf ()

bindIf () faz a mesma coisa que bind (), exceto que ele só registra uma ligação se ainda não existir (consulte bound () acima) . Poderia ser usado para registrar uma ligação padrão em um pacote e permitir que o usuário a substituísse.

  1. $ container-> bindIf (Loader :: class, FallbackLoader :: class);
  2. Não existe nenhum método `singletonIf ()`, mas você pode usar `bindIf ($ abstract, $ concrete, true)` em vez disso:
  3. ``` php
  4. $ container-> bindIf (Loader :: class, FallbackLoader :: class, true) ;

Ou escreva-o na íntegra:

  1. if (! $ Container-> bound (Loader :: class)) {
  2. $ container-> singleton (Loader :: class, FallbackLoader :: class);
  3. }

resolved ()

O métodoresolved ()retorna true se uma classe tiver sido resolvida anteriormente.

  1. var_dump ($ container-> resolved (Database :: class)); // false
  2. $ container-> make (Database :: class);
  3. var_dump ($ container-> resolvido (Database :: class)); // true

Não sei ao certo o que é útil … É redefinido se unset () for usado (consulte bound () acima).

  1. unset ($ container [Database :: class]);
  2. var_dump ($ container-> resolvido (Database :: class)); // false

factory ()

O métodofactory ()retorna um fechamento que não aceita parâmetros e chamamake ().

  1. $ dbFactory = $ container-> factory (Database :: class);
  2. $ db = $ dbFactory ();

Não sei ao certo o que é útil …

wrap ()

O método wrap () fecha um fechamento para que suas dependências sejam injetadas quando executadas. O método de quebra aceita uma matriz de parâmetros; o fechamento retornado não tem parâmetros:

  1. $ cacheGetter = function (Cache $ cache, $ key) {
  2. retornar $ cache-> get ($ key);
  3. };
  4. $ usernameGetter = $ container-> wrap ($ cacheGetter, ['nome de usuário']);
  5. $ nome de usuário = $ nome de usuárioGetter ();

Não sei para que serve, pois o fechamento não requer parâmetros …

Nota: Este método não faz parte da [Interface do contêiner] (https://github.com/laravel /framework/blob/5.4/src/Illuminate/Contracts/Container/Container.php), apenas a [classe Container] concreta (https://github.com/laravel/framework/blob/5.4/src/Illuminate/Container/ Container.php) .

afterResolving ()

O método afterResolving () funciona exatamente da mesma forma que resolving (), exceto que os retornos de chamada “afterResolving” são chamados após os retornos de chamada “resolvendo”. Não tenho certeza de quando isso seria útil …

E finalmente …

  • isShared () - Determina se um determinado tipo é um singleton / instância compartilhado
  • isAlias ​​() - Determina se um determinado string é um alias registrado
  • hasMethodBinding () - Determina se o contêiner possui um determinado método de ligação
  • getBindings () - Recupera a matriz bruta de todas as ligações registradas
  • getAlias ​​($ abstract) - Resolve um alias para o classe subjacente / nome da ligação
  • forgetInstance ($ abstract) - Limpa um único objeto de instância
  • forgetInstances () - Limpa todos os objetos de instância
  • flush () - Limpa todas as ligações e instâncias, redefinindo efetivamente o contêiner
  • setInstance () - Substitui a instância usada por getInstance () (Dica: use setInstance (null) para limpá-la, então a seguir vez que gerará uma nova instância)

Nota: Nenhum dos métodos nesta última seção faz parte da [Interface do contêiner] (https://github.com/laravel/framework/tree/6.x/src/ Illuminate / Contracts / Container / Container.php) .


  • Renato Lucena
Share
About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment