Neste artigo vamos conhecer o Koin, uma ferramenta de injeção de dependência desenvolvida em Kotlin como alternativa ao Dagger.
A técnica de injeção de dependência é muito comum no mundo dos desenvolvedores android pela necessidade de reutilização de objetos nos projetos. Mas importante ressaltarmos que sua implementação não é muito trivial.
Pensando nessa necessidade e outras, é muito comum a comunidade utilizar soluções prontas, como o caso das famosas ferramentas de injeção de dependência.
Vamos lá?
O que é injeção de dependência?
Por exemplo, quando instanciamos as dependências em algum momento do código, o próprio framework de injeção de dependência realiza esses passos pra gente.
Principais benefícios
O grande benefício é delegar a responsabilidade de inicialização das dependências, permitindo que membros do projeto apenas peçam o que precisam e a instância é fornecida automaticamente de acordo com o escopo necessário, como por exemplo, um Singleton ou Factory (instância sempre nova).
Dessa forma, temos menos trabalho de configuração e focamos no que é necessário.
O uso de Koin no projeto dá aquela impressão de que tudo funciona de uma maneira bem mais simples porque sua configuração é simples. Com ele, nós, desenvolvedores temos menos trabalho. Maravilha, não?
O Koin é uma lib externa, portanto, precisamos adicioná-lo como uma dependência no gradle do seu projeto android:
// Current stable version
koin_version= “2.1.5”
// Koin for Android
implementation “org.koin:koin-android:$koin_version”
// Koin Android Scope feature
implementation “org.koin:koin-android-scope:$koin_version”
// Koin Android ViewModel feature
implementation “org.koin:koin-android-viewmodel:$koin_version”
Ao sincronizar o projeto, temos acesso as classes do Koin.
Configurações do Koin
Sua base de configuração é por meio de seus módulos, que são as entidades que mantém as instruções de como as dependências devem ser inicializadas. Isso significa que a partir deles, ensinamos para o Koin como ele deve injetar as dependências pra gente.
val myModule = module {
// Your definitions …
}
Para configurar é bem simples, basta utilizar a função module(), que é uma Higher-Order Function, e definir a instância desejada a partir da expressão lambda.
class ComponentA()
class ComponentB(val componentA : ComponentA)
val moduleA = module {
// Singleton ComponentA
single { ComponentA() }
}
val moduleB = module {
// Singleton ComponentB with linked instance ComponentA
single { ComponentB(get()) }
}
Ao definir um módulo, somos capazes de injetar as instâncias que foram definidas dentro dele, porém, é necessário inicializar o Koin a partir da função startKoin() dentro de uma entidade que tenha referência ao Context do Android. Podemos fazer essa inicialização no onCreate() da nossa Application.
class MyAplication: Application()
{
override fun onCreate() {
super.onCreate()
// Start Koin with moduleA & moduleB
startKoin{
// declare used Android context
androidContext(this@MyAplication)
// declare modules
modules(moduleA, moduleB)
}
}
Se você ainda não sabe como se usa uma aplication no Android, vale a pena a leitura antes.
Com o Koin inicializado, podemos injetar as dependências como uma delegated property utilizando a keyword inject():
class MainActivity : AppCompatActivity() {
private val componentB: ComponentB by inject()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Assim como na inicialização via lazy, ao utilizar delegated properties, ganhamos a vantagem de manter a property imutável.
Desse jeito você consegue usar o koin no seu projeto android.
Conclusão
✅ Conseguimos aprender como configurar uma solução para injeção de dependência no Android utilizando o Koin.
Se estiver precisando de um modelo de projeto já implementado eu deixei um no meu gitHub
Precisa de um modelo de projeto já implementado? Deixei um no meu Github.
Ainda ficou com alguma dúvida no assunto? Não deixe de nos contar nos comentários pra gente continuar o papo!