Introdução ao Dagger 2

Direitos de imagem: keystrokecountdown

O Dagger 2 é um framework mantido pela google que tem por objetivo realizar a injeção de dependência em projetos Android e Java. Ele foi criado a partir do Dagger 1 que foi desenvolvido pela Square.

Neste artigo é mostrado a diferença entre o Dagger 1 e o Dagger 2.

Inversão de dependência e injeção de dependência

O princípio da inversão de dependência trata-se de uma maneira específica para desacoplar as dependências entre os objetos. O objetivo deste princípio é a redução do acoplamento entre os componentes através de uma camada de abstração.

A inversão de dependência é um princípio do SOLID. Em sua definição, temos:

  1. Componentes de mais alto nível não devem depender de componentes de níveis mais baixos, mas ambos devem depender de abstrações.
  2. Abstrações não devem depender de implementações, mas as implementações devem depender de abstrações.

Vejamos um exemplo:

Código acoplado, dependendo do objeto e não de uma abstração

O trecho de código acima possui alguns problemas:

  1. O código viola o princípio de inversão de dependência: a classe Exemplo conhece os detalhes da classe Usuario, ou seja, Exemplo depende da implementação de Usuario e não de sua abstração.
  2. Código acoplado: para listar os pedidos do usuário, é criado uma instância de Usuario, nossa classe mostrada acima, possui então uma dependência com a classe Usuario. Com isso, qualquer alteração em Usuario afetará a classe Exemplo.

Para resolvermos o item 1, nossa classe Exemplo deverá passar a depender da abstração de Usuario, que chamaremos aqui de UsuarioContrato:

Para resolvermos o item 2, devemos remover o acoplamento do código, podemos fazer isso utilizando um construtor:

Com isso, nossa classe não precisa mais criar uma instância de Usuario, agora ela pede/recebe de outra classe ou entidade.

Com as mudanças feitas, temos:

Passar a dependência pelo construtor é uma forma de remover da nossa classe a responsabilidade de instanciar um objeto. Essa é uma forma de fazer a injeção de dependência, que é uma forma de implementar a inversão de dependência.

Agora sempre que precisarmos utilizar nossa classe Exemplo, devemos fazer:

O Dagger 2

O Dagger 2 é uma forma fornecer as dependências utilizadas em nossa classe Exemplo através de códigos gerados automaticamente. Ele baseia-se na JSR 330 que define um conjunto de anotações para usar em classes injetáveis buscando maximizar a reusabilidade, testabilidade e manutenibilidade de um código.

Dentre essas anotações temos:

  • @Inject: Anotação utilizada quando se necessita pedir alguma dependência.
  • @Module: Anotação utilizada em classes que fornecem dependências.
  • @Provides: Anotação utilizadas em métodos que proveem dependências, os métodos provedores são encontrados nas classes com a anotação @Module.
  • @Component: São basicamente injetores, uma ponte entre módulos e provides, neles definimos quem pode utilizar nossos módulos e quais módulos são utilizados.

Utilizando o Dagger 2 para resolver o nosso problema

Até aqui temos que para utilizar um objeto de Exemplo devemos fazer:

Para utilizar o Dagger 2, são necessários os passos abaixo:

Configuração do gradle:

Você pode checar a versão corrente no repositório do Dagger 2.

Criar um Module

Para utilizar um dos nossos provides, devemos utilizar a anotação Inject:

Ao utilizar o Inject no código acima, estamos pedindo para que seja fornecido um objeto de Exemplo. O Dagger 2 verifica qual o objeto solicitado e busca em seus provides:

Ao prover uma instância de Exemplo, o Dagger 2 checa que esta possui uma dependência de Usuario e busca essa dependência em seus provedores:

Criar um Component

Fornecer nosso Component

Devemos disponibilizar nosso ComponenteExemplo em um local que seja acessível a todos. Normalmente é criada uma referência junto com nossa classe Application do projeto:

A classe DaggerComponentExemplo é gerada em tempo de compilação (precisa fazer o build do projeto).

Informar sobre o uso do Module

Agora precisamos informar ao Dagger 2 que nossa classe fará uso de um dos nossos Components:

Feito os passos acima, sempre que precisarmos de uma instância de Exemplo basta utilizar a anotação Inject.

Utilizando a injeção de dependência, nós temos uma facilidade muito grande para realizar, por exemplo, uma troca na implementação da classe Usuario. Isso ocorre pois não dependemos mais da implementação da classe Usuario, mas sim de sua abstração (UsuarioContrato).

Até aqui temos:

Caso seja necessário realizar uma mudança para uma nova implementação, é necessário apenas atualizar nosso provides:

Pronto! Agora ao solicitar a injeção de UsuarioContrato, será fornecido a dependência utilizando a nova implementação de nossa classe. Muito prático!

E é isso! Temos o básico sobre como utilizar o Dagger 2!

Conclusão

O princípio de inversão de dependência é interessante para evitar o acoplamento. A injeção de dependência é uma forma de fazer isso, o Dagger 2 é uma forma de fazer a injeção de dependência. Ele não é insubstituível, porém facilita o trabalho de evitar acoplamento e organizar todas as dependências do nosso projeto.

O código de exemplo utilizado pode ser encontrado aqui.

Você pode encontrar mais sobre o assunto:
[1] [2] [3]