Flutter - Injeção de dependência - II


Hoje veremos o conceito de injeção de dependência(ID) no Flutter e as abordagens para usar este recurso e obter um baixo acoplamento.

Continuando a primeira parte do artigo veremos como usar o get_it para realizar a injeção de dependência e obter um baixo acoplamento.

Flutter :  get_it

O get_it é conhecido como um Service Locator simples. Com ele você registra seus tipos em uma interface  e fornece a implementação concreta a ela. Dessa forma, você se beneficia do desenvolvimento em uma interface que também facilita o teste de unidade, porque você pode fornecer implementações específicas de teste.

Nota: Um Service Locator é um padrão de projeto (antipadrão) usado para  encapsular os processos envolvidos na obtenção de um serviço com uma camada de abstração. Esse padrão usa um registro central conhecido como "localizador de serviço" que, mediante solicitação, retorna as informações necessárias para executar uma determinada tarefa.

Para usar este recurso você tem que adicionar a referência ao pacote do get_it no arquivo pubspec.yaml:

...
dependencies:
  flutter:
    sdk: flutter
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  cloud_firestore: ^0.13.0+1
  get_it: ^3.1.0
...

A seguir precisamos configurar o nosso Service Locator (SL).

Em seu projeto Flutter na pasta lib crie um arquivo na raiz do projeto que pode ser chamado de service_locator.dart o qual vai conter a variável global (variável de ambiente) para o SL.

import 'package:cadastro/model/produto.dart';
import 'package:get_it/get_it.dart';
GetIt servicelocator = GetIt();
 void setupLocator() {
     //a definir    
}

Os tipos precisam ser registrados antes do aplicativo ser iniciado. Portanto, no arquivo main.dart, chamaremos setupLocator antes que o aplicativo seja iniciado.

import 'service_locator.dart';
import 'package:flutter/material.dart';
void main() {
  setupLocator();
  runApp(MyApp());
}

Agora podemos registrar nosso Produto, e, usando get_it, os tipos de classe podem ser registrados de duas maneiras.

Factory : Quando você solicita uma instância do tipo ao provedor de serviços, sempre obtém uma nova instância. É bom para registrar as ViewModels que precisam executar a mesma lógica no início ou que precisam ser novos quando a exibição for aberta. 


Singleton: Singletons podem ser registrados de duas maneiras :

  1. Fornecer uma implementação no registro;
    Ex:  servicelocator.registerSingleton<Produto>(new Produto());
     
  2. fornecer um lambda que será chamado na primeira vez que sua instância for solicitada(LazySingleton);
    Ex:
     
    servicelocator.registerFactory(() => Produto());

 O Localizador mantém uma única instância do seu tipo registrado e sempre retornará essa instância.

Registraremos nosso Produto como um singleton para que haja apenas uma instância enquanto o aplicativo estiver em execução e o código do service_locator.dart ficará assim:

import 'package:cadastro/model/produto.dart';
import 'package:get_it/get_it.dart';
GetIt servicelocator  = GetIt();
 void setupLocator() {
    servicelocator.registerFactory(() => Produto());
}

E com isso concluímos a configuração do Service Locator e do get_it e agora em nosso arquivo home_page.dart podemos definir o código onde podemos obter uma instância de Produto a partir do nosso localizador servicelocator :

...
 @override
  Widget build(BuildContext context) {

    // obtem o produto do locator
    var produto = servicelocator<Produto>();

    return Scaffold(
      body: Center(
        child: Text(produto.nome),
      ),
    );
  }

Bem simples, não é mesmo !!!!

Se você usar o get_it atente para o seguinte detalhe:

SEMPRE use o mesmo estilo para importar seus arquivos de projeto como caminhos relativos OU como pacote.

NÃO misture o estilo porque atualmente o Dart trata tipos importados de maneiras diferentes como dois tipos diferentes, embora ambos façam referência ao mesmo arquivo.

A favor desta abordagem temos que : 

E como desvantagem temos que  

Na próxima parte do artigo veremos a injeção de dependência usando o Provider.

 

"Para que os seus corações sejam consolados, e estejam unidos em amor, e enriquecidos da plenitude da inteligência, para conhecimento do mistério de Deus e Pai, e de Cristo, Em quem estão escondidos todos os tesouros da sabedoria e da ciência."
Colossenses 2:2,3

Referências:


José Carlos Macoratti