Dagger: um rápido injetor de dependências Java

marcossilvano
Quick Mobile Labs
Published in
4 min readSep 5, 2016

Dagger é um framework Java para gerenciar injeção de dependências. Ele é relativamente simples de ser configurado. Todo o trabalho feito pelo Dagger é executado em tempo de compilação e o código gerado é fácil de compreender. Além disso, as dependências são ligadas por um grafo de componentes. Ao usar Dagger você deixa o código mais testável e mais limpo (já que você vai evitar blocos com instanciações).

Uso

O Dagger injeta dependências em elementos anotados. Caso você tenha classes mais complexas com alguma configuração, você deverá iniciar o sistema de grafos com os componentes para que o Dagger trabalhe com eles.

A mais simples das injeções é declarada pela anotação @Inject. Ela é usada para declarar dependências não configuráveis que podem ser injetadas. A anotação @Inject pode ser usada em construtores, atributos e métodos (embora em métodos não seja uma boa prática).

Por exemplo, no código abaixo, temos a classe BClass criando uma instância da classe AClass com a anotação @Inject. Se o construtor da classe AClass tiver parâmetros, é preciso o uso do @Inject no construtor, caso contrário não é necessário.

@Inject funciona em casos simples. Não foi feito para ser usado em interface, objetos configuráveis e classes de frameworks (terceiros).

Em caso de objetos configuráveis, é possível criá-los da seguinte forma: adicione a anotação @Module na classe e a anotação @Provides no método configurável. Esse objeto configurável pode ou não ter paramêtros. Após fazer isso, você terá um componente, entretanto, ele ainda não foi incluído no grafo de componentes.

Para adicionar o componente no grafo é preciso usar uma interface. Basta colocar a anotação @Component nela e passar como parâmetro a classe com a anotação @Module (veja no exemplo abaixo).

O Dagger irá criar uma classe (no nosso exemplo, DaggerSomeClass_Cinterface.class) que usaremos da seguinte forma abaixo para seja feita a inserção do componente no grafo.

Caso o construtor e os métodos anotados com o @Provides sejam públicos e o construtor não tenha parâmetro, pode-se usar .create() ao invés de .builder().build(). Isso irá retornar uma instancia do CClass que poderá ser usada para ter acesso aos componentes adicionados no grafo.

Se o Module tiver um construtor, é preciso que o Module seja iniciado passando uma instancia dele mesmo para o método com o mesmo nome da instancia do modulo. Confuso, né? Aqui um exemplo pra você entender melhor:

É importante saber que um componente pode ter um subcomponente, e a interface anotada com `@Component` também pode ter múltiplos métodos. Além disso, pode ser injetado uma lista ou mapa de dependências usando `@IntoSet` e `@IntoMap` e essas estruturas serão adicionadas no grafo de componentes e podem ser acessados como set e map.

Dagger também fornece anotações para ter um controle mais flexível dos componentes:

  • `@Singleton` anotação que define que cada instância será única para cada cliente.
  • `@Reusable` define que cada instância pode ser reutilizada e será restrita apenas ao mesmo componente.
  • `Lazy<SomeClass>` é usado em um atributo com @Inject, isso faz com que sempre que uma injeção de dependência for requisitada, se for possível, ele irá retornar a mesma instancia.
  • `Provider<SomeClass>` é tambem usado em um atributo anotado com @Inject, mas ao contrario do Lazy, toda vez que uma instância for requerida, irá ser retornado uma nova instancia.

Como conclusão, posso dizer que achei essa ferramenta complexa, mas com qualidades interessantes. Acredito que após adquirir conhecimento sobre ela, tira-se um grande proveito dessas qualidades. Particularmente, em projetos simples (sem necessidade da aplicação de padrões de complexos) eu não a utilizaria.

--

--