A Square, empresa focada em plataformas móveis de pagamentos, apresentou a biblioteca Dagger, um "injetor de dependências para Android e Java". O código foi disponibilizado no GitHub.
A Injeção de Dependências (também conhecida como Inversão de Controle) está presente em diversos frameworks populares como Spring ou Google Guice. Porém, estes últimos foram desenvolvidos pensando na JVM e não em ambientes móveis como o Android. Enquanto o RoboGuice procura melhorar a usabilidade do Guice no Android, o Dagger segue uma abordagem diferente, concentrando-se em funcionalidades simplificadas e melhor desempenho.
O Dagger atualmente suporta:
- Injeção de construtores utilizando as anotações da JSR-330;
- Criação de objetos utilizando a anotação @Provides;
- Um contexto central para a árvore de dependências;
- Injeções lazy (sob demanda) para recursos mais pesados;
- Sintaxes diferentes para várias implementações da mesma interface;
- Injeção estática, para ambientes legados;
- Validação durante a compilação de bindings (vínculos).
O Dagger suporta a anotação Inject padrão, também oferecida pelo Spring e pelo Guice. Mas no Dagger apenas a injeção de construtores é suportada. Não é possível fazer a injeção de métodos (uma alternativa para injetar dependências em uma classe). O Dagger também oferece a anotação @Provides, que funciona de forma similar à mesma anotação do Guice.
Uma vez que as dependências são definidas, as classes injetadas são obtidas através do ObjectGraph que armazena uma árvore de todos objetos inicializados pelo Dagger. O mecanismo é similar ao usado pelo ApplicationContext do Spring; também se assemelha ao Injector do Guice. O Dagger compartilha, ainda, o conceito de Módulos (uma coleção de vínculos) presentes no Guice.
Algumas dependências, como pool de conexões, são muito custosas para inicializar de maneira atômica. Para esses casos, o Dagger suporta inicializações de dependências sob demanda. Novamente, a sintaxe é similar à do Guice. No caso de existirem múltiplas implementações para um recurso, o Dagger segue a convenção de utilizar a anotação @Named.
Por fim, o projeto oferece injeção de código legado que ainda utiliza Factories ao invés de injeção de dependências. Até o momento, são suportadas apenas algumas funcionalidades presentes no Google Guice. O escopo reduzido se deve à sua criação voltada ao Android. A ausência mais marcante, como mencionado, é a de injeção de métodos e campos.
O Dagger sacrifica essa funcionalidade mas melhora muito o processo de checagem/detecção de erros. Geralmente, erros de injeção de dependências são reportados durante a execução da aplicação. No entanto, o Dagger faz uma validação em tempo de compilação, exibindo mensagens de erro caso haja problemas com bindings. Essa funcionalidade pode facilitar o desenvolvimento de aplicações que serão executadas no Android.
Outra grande diferença é a falta de escopos. O Dagger suporta apenas a anotação @Singleton e nada mais. Novamente isso é esperado, já que ambiente Android tem necessidades diferentes se comparado ao ambiente web (que possui escopos de requisições e de sessão).
Vale ressaltar que os usuários do Spring não apenas notaram o Dagger como também criaram duas novas pendências para próximas versões do Spring, com base nas suas funcionalidades. O primeiro item é o fato de que o Spring apenas faz injeção de classes que tenham sido anotadas; o segundo é a falta de capacidade do Spring em diferenciar classes que implementem interfaces com tipos genéricos.
Até o momento, a única documentação presente no Dagger é o arquivo README. O código é aberto e licenciado sob a licença Apache 2. O projeto ainda não tem versão oficial (não existe nem um label no código), o que deve ser levado em conta ao avaliar a utilização do projeto em produção.