Não é mágica 🪄 | Gerenciamento de Dependências Cíclicas
Enquanto escrevia uma aula sobre Injeção de Dependência, lembrei de uma dúvida que tive no meio da minha carreira e que é muito comum entre programadores Plenos: Como resolver dependências cíclicas?
Eu digo entre "Plenos" porque é nesse momento que começamos a questionar como (DI) funcionam, enquanto ainda acreditamos que muita coisa é feita magicamente. Enfim!
Gerenciamento de dependências cíclicas é a capacidade de lidar com situações em que uma classe depende de outra classe, que por sua vez, depende da primeira classe. wow!
Isso pode ocorrer quando duas ou mais classes precisam ser instanciadas em conjunto e são dependentes umas das outras.
Exemplo de dependência cíclica:
class A {
lateinit var b: B
fun foo() {...}
}
class B {
lateinit var a: A
fun bar() {...}
}
Esse tipo de situação pode causar um loop infinito, onde a biblioteca que tu usa para fazer (DI) fica tentando resolver as dependências, ou pode causar erros em tempo de execução.
A maioria das bibliotecas de (DI), como o Dagger por exemplo para JAVA, tem suporte para gerenciar dependências cíclicas. E isso geralmente é feito através da definição de "providers" para as dependências cíclicas.
Um provider é uma função que fornece uma instância de uma dependência, que é chamada apenas quando a dependência é realmente necessária.
Isso permite que as dependências cíclicas sejam resolvidas de forma eficiente e evita problemas em tempo de execução.
class CyclicModule {
fun provideA(b: Provider<B>): A {
val a = A()
a.b = b.get()
return a
}
fun provideB(a: Provider<A>): B {
val b = B()
b.a = a.get()
return b
}
}
Isso permite que a biblioteca de injeção de dependência crie uma instância de A
e B
separadamente, sem entrar em um loop infinito. 👍