Como utilizar o GetiT com o Adapter no Flutter

Neste artigo, vamos explorar como GetIt e Adapter Pattern trabalham juntos para desacoplar seu código, facilitar a manutenção e tornar seu app mais escalável.
Vamos lá?
Como o GetIt é útil em projetos Flutter?
Você já se viu perdido no meio de um emaranhado de dependências no seu app Flutter?
Imagine que sua equipe está desenvolvendo um aplicativo de delivery.
Tudo caminha bem até que surge a necessidade de integrar um novo serviço de pagamento. O problema?
O código já espalha controllers, repositories e services por 20 arquivos diferentes, e cada widget instancia suas próprias dependências. No primeiro teste, o app quebra. Os usuários reclamam, e você passa a madrugada refatorando código.
Agora imagine um assistente que organiza essa bagunça para você. Esse é o papel do GetIt, uma biblioteca que gerencia suas dependências de forma centralizada, garantindo que cada parte do seu app receba exatamente o que precisa, quando precisa. Nada de criar objetos manualmente ou passar serviços por construtores o tempo todo.

Mas só isso resolve o problema? Não completamente.
Para que módulos diferentes do seu app conversem sem depender diretamente uns dos outros, entra em cena outro aliado: o padrão de projeto adapter, que atua como um tradutor, permitindo que você substitua um serviço sem alterar todas as partes do código que o utilizam.

O que é injeção de dependência?
A injeção de dependências (ID) visa a centralizar a criação e fornecimento das dependências. Em vez de cada parte do código se preocupar com o como criar um serviço, ela apenas solicita o que precisa e recebe a instância correta, como vemos nessa imagem:

Por que usar injeção de dependências?
Imagine que você viajou para outro país e, ao chegar no hotel, percebeu que a tomada é completamente diferente dos pinos do seu carregador. O que fazer? Trocar toda a fiação elétrica do quarto? Claro que não!
A solução inteligente é usar um adaptador , que faz o seu carregador funcionar, e sem modificar toda a infraestrutura.
A injeção de dependências (ID) segue essa mesma lógica. Em vez de cada parte do seu código criar e gerenciar suas próprias instâncias, ela solicita a dependência certa, sem preocupar-se com como ela é fornecida. Isso deixa o seu código mais flexível e preparado para mudanças.
O que a injeção de dependências resolve?
Há três principais pontos:
- Código acoplado: se um widget cria suas próprias instâncias, ele fica preso a uma implementação específica. Trocar um serviço vira um retrabalho desnecessário;
- Testes complicados: sem ID, testar o código exige criar todas as dependências do zero. Com ID, basta trocar um serviço real por um mock e pronto;
- Gerenciamento de estado bagunçado: criar instâncias sem controle pode gerar cópias desnecessárias, dificultando o fluxo de dados no app.
E no Flutter?
A injeção de dependências ajuda a organizar a criação e distribuição de objetos essenciais no app.
No Flutter, isso significa gerenciar controladores de estado, serviços de API, banco de dados e cache sem instanciá-los manualmente toda hora.
Ou seja, menos código repetitivo e um fluxo de dados muito mais previsível.
O que é o GetIT no Flutter?
Agora que entendemos a importância da injeção de dependências, vamos falar sobre a ferramenta que simplifica isso no Flutter: GetIt.
Se cada widget do seu app criar suas próprias dependências, o código vai ficando confuso.
É como se, toda vez que precisasse acender a luz, você tivesse que ir ao disjuntor (em vez de simplesmente usar o interruptor).
O GetIt funciona exatamente assim, pois registra as dependências em um único lugar e entrega sempre que necessário, sem instanciar manualmente a cada uso.
Por que usar GetIt?
Existem várias formas de gerenciar dependências no Flutter, como provider e riverpod.
O diferencial é que o GetIt não se preocupa com gerenciamento de estado, apenas com fornecer as dependências no momento certo.
Outra razão é que, com GetIt, você escolhe como cada dependência deve ser gerenciada: algumas podem ser singletons (criadas uma única vez e reutilizadas); outras podem ser instanciadas sob demanda, como em um modelo de fábrica.
No fim das contas, o GetIt economiza tempo e organiza o seu código. Ninguém gostaria de perder horas caçando onde uma dependência foi instanciada ou refatorando chamadas espalhadas pelo projeto. A ideia, aqui, é que tudo fique no lugar certo desde o começo.
O que o adapter pattern tem a ver com o GetIt?
Agora imagine que, em um belo dia, você precisa trocar o serviço de API do seu app ou substituir o banco de dados local por uma solução na nuvem.
Se cada parte do código estiver amarrada diretamente a essas implementações, qualquer mudança vira um pesadelo.
É aí que entra o adapter pattern (padrão), que funciona como um tradutor entre o código e a implementação real, permitindo que seu app dependa apenas de uma interface genérica. Assim, quando precisar trocar um serviço, basta criar um novo adaptador sem mexer no resto do código.
O GetIt entra nesse jogo garantindo que a implementação correta seja injetada automaticamente onde for necessária.
Dessa forma, você ganha um sistema flexível, pronto para mudanças sem quebrar tudo.
Mão na massa: como implementar o GetIt em projetos Flutter?
Agora que vimos como o GetIt pode simplificar a injeção de dependências, é hora de colocar a mão na massa.
Vamos entender passo a passo como instalar, configurar, registrar serviços e recuperar dependências no seu app Flutter; essa abordagem centraliza o controle das instâncias e facilita a manutenção do código.
Como instalar o GetIT em projetos Flutter?
Primeiro, adicione o GetIt ao seu projeto. No terminal, rode o comando:
flutter pub add get_it
Em seguida, crie um arquivo (por exemplo, “locator.dart”) para configurar o GetIt. Dentro do arquivo, crie uma instância global que armazenará todas as dependências:
import 'package:get_it/get_it.dart';
final getIt = GetIt.instance;
void setupInjection() {
// As dependências serão registradas aqui.
}
Agora podemos caminhar para fazer registros de serviços, então pense que você tenha uma interface para fazer requisições HTTP, definida pelo HttpAdapter:
import 'package:http/http.dart' as http;
abstract class HttpAdapter {
Future<http.Response> get(String url);
}
Crie uma implementação dessa interface:
class HttpAdapterImpl implements HttpAdapter {
final http.Client client = http.Client();
@override
Future<http.Response> get(String url) {
return client.get(Uri.parse(url));
}
}
Registre essa implementação no GetIt usando, por exemplo, o método registerLazySingleton
. Dessa forma, a instância só é criada quando for realmente necessária:
void setupInjection() {
getIt.registerLazySingleton<HttpAdapter>(() => HttpAdapterImpl());
}
Recuperando dependências no GetIt
Com o serviço registrado, você pode acessá-lo de qualquer lugar do seu app sem passá-lo como parâmetro. Por exemplo:
void fetchData() async {
final httpAdapter = getIt<HttpAdapter>();
final response = await httpAdapter.get(' https://jsonplaceholder.typicode.com/posts ');
if (response.statusCode == 200) {
print('Dados carregados, deu tudo certo!');
}
}
Essa forma de recuperar a dependência centralizada é bacana: você não precisa se preocupar com a criação manual de instâncias.
O GetIt faz essa ponte, assim como um adaptador que conecta componentes sem expor os detalhes internos.
Essa prática facilita, inclusive, a troca de implementações no futuro, sem que seja necessário alterar todos os pontos que utilizam o serviço.
O próximo passo é explorar conceitos mais avançados e boas práticas, mas essa estrutura já garante um app mais limpo e preparado para escalar.
Conceitos avançados: aprofundando no GetIt
Até aqui, vimos como o GetIt simplifica a injeção de dependências e como podemos registrar e recuperar serviços no app.
E, para tirar o máximo proveito da ferramenta, é importante entender como os diferentes tipos de registro funcionam e como gerenciar o ciclo de vida das dependências.
Tipos de registro no GetIt
O GetIt oferece três formas principais de registrar dependências:
Singleton: cria e mantém uma única instância da dependência durante toda a execução do app. Ideal para serviços globais, como gerenciamento de autenticação;
LazySingleton: semelhante ao singleton, mas a instância só é criada quando for realmente necessária. Isso otimiza o uso de memória;
Factory: sempre que a dependência for solicitada, uma nova instância é criada. Útil para objetos que não devem ser compartilhados entre diferentes partes do app.
Exemplo de registro de cada tipo:
void setupInjection() {
getIt.registerSingleton<AuthService>(AuthService()); // Sempre a mesma instância
getIt.registerLazySingleton<DatabaseService>(() => DatabaseService()); // Criado só quando necessário
getIt.registerFactory<ApiService>(() => ApiService()); // Nova instância sempre que chamada
}
Ciclo de vida das dependências
Cada tipo de registro afeta diretamente como as instâncias são gerenciadas dentro do app.
Os *singletons e lazy singletons são mantidos na memória até serem removidos manualmente, enquanto factories** são criados e descartados automaticamente.
Se precisar remover ou resetar uma instância, o GetIt permite fazer isso facilmente:
getIt.unregister<AuthService>(); // Remove o singleton da memória
getIt.reset(); // Reseta todas as dependências registradas
Esses conceitos são essenciais para evitar vazamento de memória e garantir que o app só mantenha na memória o que for realmente necessário.
Para se aprofundar recomendo a leitura da documentação do GetIt.
Boas práticas com GetIt
Manter o GetIt organizado evita que o código fique descontrolado com dependências espalhadas. Algumas estratégias garantem um código mais limpo e sustentável.
Organização do código com GetIt
Crie um arquivo específico para a configuração do GetIt, como ‘locator.dart’, para manter o código mais modular.
Isso facilita futuras alterações e evita que os registros se espalhem pelo projeto:
import 'package:get_it/get_it.dart';
final getIt = GetIt.instance;
void setupInjection() {
getIt.registerLazySingleton<ApiService>(() => ApiService());
}
Chame essa configuração no ‘main.dart’ antes de iniciar o app para garantir que as dependências já estejam disponíveis:
void main() {
setupInjection();
runApp(MyApp());
}
Padrões comuns no uso do GetIt
Para evitar acoplamento excessivo, uma prática comum é registrar interfaces em vez de classes concretas. Assim, você poderia trocar a implementação sem alterar todo o código.
getIt.registerLazySingleton<HttpAdapter>(() => HttpAdapterImpl());
Também é importante evitar dependências desnecessárias e descartar aquelas que não forem mais utilizadas. Isso vai deixar seu aplicativo mais leve e eficiente.
getIt.unregister<AuthService>(); // Remove uma instância específica
Com essas práticas, o GetIt continua sendo um aliado na organização do código, sem se tornar um problema.
Quando usar GetIt e quando evitar?
O GetIt é útil para serviços que precisam ser compartilhados entre diferentes partes do app, como autenticação, APIs e banco de dados. Mas nem tudo precisa ser registrado nele.
Use o GetIt quando um serviço precisa ser acessado globalmente.
Evite usá-lo para objetos que só fazem sentido dentro de um widget específico. Nesses casos, o ideal é instanciar localmente ou usar outro gerenciador de estado.
Conclusão
Ao longo deste artigo, vimos como o GetIt e o Adapter Pattern ajudam a organizar o código e desacoplar dependências no Flutter.
O GetIt centraliza a injeção de serviços, evitando instâncias espalhadas e facilitando testes.
Por sua vez, o adapter pattern permite trocar implementações sem impactar o restante do código, garantindo mais flexibilidade.
Com essas ferramentas, seu app se torna mais modular, sustentável e pronto para crescer sem dores de cabeça.
Se quiser se aprofundar, vale a pena conferir a documentação oficial do GetIt e explorar como ele pode ser combinado com outros padrões.
Além disso, a Alura tem conteúdos que podem te ajudar a evoluir ainda mais nessa jornada:
- Formação Flutter: do básico ao avançado
- Curso de Gerenciamento de Estado no Flutter
- Artigo sobre Design Patterns no Flutter
Espero que esse artigo tenha ajudado a esclarecer como o GetIt e o adapter melhoram a estrutura do seu código.
Desejo muito sucesso na sua trajetória!
Até mais!