evant / kotlin-inject

Dependency injection lib for kotlin
Apache License 2.0
1.29k stars 60 forks source link

Build fails when declaring two `Lazy` dependencies. #425

Open AdriaBosch opened 3 months ago

AdriaBosch commented 3 months ago

I acknowledge that the following graph is not ideal, but I believe it should compile without the need for any workarounds.

@Scope
annotation class Singleton

@Singleton
@Inject
class Interceptor(val client1: Lazy<Client1>, val client2: Lazy<Client2>)

@Inject
class Client1(val interceptor: Interceptor)

@Inject
class Client2(val interceptor: Interceptor)

@Inject
class Repository(val client1: Client1, val client2: Client2)

@Singleton
@Component
interface MyComponent {

    val repository: Repository
}

I was able to compile by declaring the Interceptor dependency within the component.

@Singleton
@Component
interface MyComponent {

    val interceptor: Interceptor
    val dep: Dependency
}

or by removing the @Singleton annotation from Interceptor.

evant commented 2 months ago

Ok I think I tracked down the cause of the issue. The expression for a given type is cached so it doesn't have to be recalculated when used in different places. However, when there is a a cycle that caching includes the reference to the lateinit variable, but not the lateinit variable itself. So when it's reused that variable doesn't exist.